mirror of
https://github.com/bitcoin/bitcoin.git
synced 2024-11-20 02:25:40 +01:00
Merge #15450: gui: Create wallet menu option
613de61a04
Add Create Wallet menu action (Andrew Chow)9b41cbb28f
Expose wallet creation to the GUI via WalletController (Andrew Chow)78863e2900
Add CreateWalletDialog to create wallets from the GUI (Andrew Chow)60adb21c7a
Optionally allow AskPassphraseDialog to output the passphrase (Andrew Chow)bc6d8a3662
gui: Refactor OpenWalletActivity (João Barbosa) Pull request description: This PR adds a menu option to create a new wallet. When clicked, a `CreateWalletDialog` will be created and prompt the user to name the wallet and choose whether to disable private keys, make a blank wallet, and encrypt the wallet. If the wallet is encrypted, the wallet will be born encrypted with the wallet first created blank, then encrypted, and then a new HD seed generated and set. To allow the newly created wallets to be encrypted, some changes to how encrypting a wallet works. Instead of encrypting and locking the wallet, the wallet will be encrypted and then unlocked. This is also an extra belt-and-suspenders check to make sure that encryption worked. ACKs for top commit: fanquake: ACK613de61a04
- re-reviewed on macOS. I'm going to merge this now. It's had a stack of review, and as mentioned multiple times above, lets get this into `master` so it can get more testing pre `v0.19.0`. Tree-SHA512: 3f22cc20b13703ffc90d366ae9133114832fea77f4f319da7fd85eb454f2f0bd5d7e1e6e20284dea2f370d8574f83b45669dcbbe506b994410d32e8e7a6fa877
This commit is contained in:
commit
b5a8d0cff1
@ -16,6 +16,7 @@ FORMS += \
|
|||||||
../src/qt/forms/sendcoinsentry.ui \
|
../src/qt/forms/sendcoinsentry.ui \
|
||||||
../src/qt/forms/signverifymessagedialog.ui \
|
../src/qt/forms/signverifymessagedialog.ui \
|
||||||
../src/qt/forms/transactiondescdialog.ui \
|
../src/qt/forms/transactiondescdialog.ui \
|
||||||
|
../src/qt/forms/createwalletdialog.ui
|
||||||
|
|
||||||
RESOURCES += \
|
RESOURCES += \
|
||||||
../src/qt/bitcoin.qrc
|
../src/qt/bitcoin.qrc
|
||||||
|
@ -98,6 +98,7 @@ QT_FORMS_UI = \
|
|||||||
qt/forms/addressbookpage.ui \
|
qt/forms/addressbookpage.ui \
|
||||||
qt/forms/askpassphrasedialog.ui \
|
qt/forms/askpassphrasedialog.ui \
|
||||||
qt/forms/coincontroldialog.ui \
|
qt/forms/coincontroldialog.ui \
|
||||||
|
qt/forms/createwalletdialog.ui \
|
||||||
qt/forms/editaddressdialog.ui \
|
qt/forms/editaddressdialog.ui \
|
||||||
qt/forms/helpmessagedialog.ui \
|
qt/forms/helpmessagedialog.ui \
|
||||||
qt/forms/intro.ui \
|
qt/forms/intro.ui \
|
||||||
@ -117,6 +118,7 @@ QT_MOC_CPP = \
|
|||||||
qt/moc_addressbookpage.cpp \
|
qt/moc_addressbookpage.cpp \
|
||||||
qt/moc_addresstablemodel.cpp \
|
qt/moc_addresstablemodel.cpp \
|
||||||
qt/moc_askpassphrasedialog.cpp \
|
qt/moc_askpassphrasedialog.cpp \
|
||||||
|
qt/moc_createwalletdialog.cpp \
|
||||||
qt/moc_bantablemodel.cpp \
|
qt/moc_bantablemodel.cpp \
|
||||||
qt/moc_bitcoinaddressvalidator.cpp \
|
qt/moc_bitcoinaddressvalidator.cpp \
|
||||||
qt/moc_bitcoinamountfield.cpp \
|
qt/moc_bitcoinamountfield.cpp \
|
||||||
@ -202,6 +204,7 @@ BITCOIN_QT_H = \
|
|||||||
qt/clientmodel.h \
|
qt/clientmodel.h \
|
||||||
qt/coincontroldialog.h \
|
qt/coincontroldialog.h \
|
||||||
qt/coincontroltreewidget.h \
|
qt/coincontroltreewidget.h \
|
||||||
|
qt/createwalletdialog.h \
|
||||||
qt/csvmodelwriter.h \
|
qt/csvmodelwriter.h \
|
||||||
qt/editaddressdialog.h \
|
qt/editaddressdialog.h \
|
||||||
qt/guiconstants.h \
|
qt/guiconstants.h \
|
||||||
@ -328,6 +331,7 @@ BITCOIN_QT_WALLET_CPP = \
|
|||||||
qt/askpassphrasedialog.cpp \
|
qt/askpassphrasedialog.cpp \
|
||||||
qt/coincontroldialog.cpp \
|
qt/coincontroldialog.cpp \
|
||||||
qt/coincontroltreewidget.cpp \
|
qt/coincontroltreewidget.cpp \
|
||||||
|
qt/createwalletdialog.cpp \
|
||||||
qt/editaddressdialog.cpp \
|
qt/editaddressdialog.cpp \
|
||||||
qt/openuridialog.cpp \
|
qt/openuridialog.cpp \
|
||||||
qt/overviewpage.cpp \
|
qt/overviewpage.cpp \
|
||||||
|
@ -5,8 +5,10 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <util/system.h>
|
#include <util/system.h>
|
||||||
#include <walletinitinterface.h>
|
#include <walletinitinterface.h>
|
||||||
|
#include <support/allocators/secure.h>
|
||||||
|
|
||||||
class CWallet;
|
class CWallet;
|
||||||
|
enum class WalletCreationStatus;
|
||||||
|
|
||||||
namespace interfaces {
|
namespace interfaces {
|
||||||
class Chain;
|
class Chain;
|
||||||
@ -74,6 +76,11 @@ std::shared_ptr<CWallet> LoadWallet(interfaces::Chain& chain, const std::string&
|
|||||||
throw std::logic_error("Wallet function called in non-wallet build.");
|
throw std::logic_error("Wallet function called in non-wallet build.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WalletCreationStatus CreateWallet(interfaces::Chain& chain, const SecureString& passphrase, uint64_t wallet_creation_flags, const std::string& name, std::string& error, std::string& warning, std::shared_ptr<CWallet>& result)
|
||||||
|
{
|
||||||
|
throw std::logic_error("Wallet function called in non-wallet build.");
|
||||||
|
}
|
||||||
|
|
||||||
namespace interfaces {
|
namespace interfaces {
|
||||||
|
|
||||||
class Wallet;
|
class Wallet;
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include <primitives/block.h>
|
#include <primitives/block.h>
|
||||||
#include <rpc/server.h>
|
#include <rpc/server.h>
|
||||||
#include <shutdown.h>
|
#include <shutdown.h>
|
||||||
|
#include <support/allocators/secure.h>
|
||||||
#include <sync.h>
|
#include <sync.h>
|
||||||
#include <txmempool.h>
|
#include <txmempool.h>
|
||||||
#include <ui_interface.h>
|
#include <ui_interface.h>
|
||||||
@ -43,6 +44,7 @@ fs::path GetWalletDir();
|
|||||||
std::vector<fs::path> ListWalletDir();
|
std::vector<fs::path> ListWalletDir();
|
||||||
std::vector<std::shared_ptr<CWallet>> GetWallets();
|
std::vector<std::shared_ptr<CWallet>> GetWallets();
|
||||||
std::shared_ptr<CWallet> LoadWallet(interfaces::Chain& chain, const std::string& name, std::string& error, std::string& warning);
|
std::shared_ptr<CWallet> LoadWallet(interfaces::Chain& chain, const std::string& name, std::string& error, std::string& warning);
|
||||||
|
WalletCreationStatus CreateWallet(interfaces::Chain& chain, const SecureString& passphrase, uint64_t wallet_creation_flags, const std::string& name, std::string& error, std::string& warning, std::shared_ptr<CWallet>& result);
|
||||||
|
|
||||||
namespace interfaces {
|
namespace interfaces {
|
||||||
|
|
||||||
@ -258,6 +260,13 @@ public:
|
|||||||
{
|
{
|
||||||
return MakeWallet(LoadWallet(*m_interfaces.chain, name, error, warning));
|
return MakeWallet(LoadWallet(*m_interfaces.chain, name, error, warning));
|
||||||
}
|
}
|
||||||
|
WalletCreationStatus createWallet(const SecureString& passphrase, uint64_t wallet_creation_flags, const std::string& name, std::string& error, std::string& warning, std::unique_ptr<Wallet>& result) override
|
||||||
|
{
|
||||||
|
std::shared_ptr<CWallet> wallet;
|
||||||
|
WalletCreationStatus status = CreateWallet(*m_interfaces.chain, passphrase, wallet_creation_flags, name, error, warning, wallet);
|
||||||
|
result = MakeWallet(wallet);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
std::unique_ptr<Handler> handleInitMessage(InitMessageFn fn) override
|
std::unique_ptr<Handler> handleInitMessage(InitMessageFn fn) override
|
||||||
{
|
{
|
||||||
return MakeHandler(::uiInterface.InitMessage_connect(fn));
|
return MakeHandler(::uiInterface.InitMessage_connect(fn));
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include <amount.h> // For CAmount
|
#include <amount.h> // For CAmount
|
||||||
#include <net.h> // For CConnman::NumConnections
|
#include <net.h> // For CConnman::NumConnections
|
||||||
#include <netaddress.h> // For Network
|
#include <netaddress.h> // For Network
|
||||||
|
#include <support/allocators/secure.h> // For SecureString
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@ -27,6 +28,7 @@ class RPCTimerInterface;
|
|||||||
class UniValue;
|
class UniValue;
|
||||||
class proxyType;
|
class proxyType;
|
||||||
struct CNodeStateStats;
|
struct CNodeStateStats;
|
||||||
|
enum class WalletCreationStatus;
|
||||||
|
|
||||||
namespace interfaces {
|
namespace interfaces {
|
||||||
class Handler;
|
class Handler;
|
||||||
@ -200,6 +202,9 @@ public:
|
|||||||
//! with handleLoadWallet.
|
//! with handleLoadWallet.
|
||||||
virtual std::unique_ptr<Wallet> loadWallet(const std::string& name, std::string& error, std::string& warning) = 0;
|
virtual std::unique_ptr<Wallet> loadWallet(const std::string& name, std::string& error, std::string& warning) = 0;
|
||||||
|
|
||||||
|
//! Create a wallet from file
|
||||||
|
virtual WalletCreationStatus createWallet(const SecureString& passphrase, uint64_t wallet_creation_flags, const std::string& name, std::string& error, std::string& warning, std::unique_ptr<Wallet>& result) = 0;
|
||||||
|
|
||||||
//! Register handler for init messages.
|
//! Register handler for init messages.
|
||||||
using InitMessageFn = std::function<void(const std::string& message)>;
|
using InitMessageFn = std::function<void(const std::string& message)>;
|
||||||
virtual std::unique_ptr<Handler> handleInitMessage(InitMessageFn fn) = 0;
|
virtual std::unique_ptr<Handler> handleInitMessage(InitMessageFn fn) = 0;
|
||||||
|
@ -18,12 +18,13 @@
|
|||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
|
|
||||||
AskPassphraseDialog::AskPassphraseDialog(Mode _mode, QWidget *parent) :
|
AskPassphraseDialog::AskPassphraseDialog(Mode _mode, QWidget *parent, SecureString* passphrase_out) :
|
||||||
QDialog(parent),
|
QDialog(parent),
|
||||||
ui(new Ui::AskPassphraseDialog),
|
ui(new Ui::AskPassphraseDialog),
|
||||||
mode(_mode),
|
mode(_mode),
|
||||||
model(nullptr),
|
model(nullptr),
|
||||||
fCapsLock(false)
|
fCapsLock(false),
|
||||||
|
m_passphrase_out(passphrase_out)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
@ -90,7 +91,7 @@ void AskPassphraseDialog::setModel(WalletModel *_model)
|
|||||||
void AskPassphraseDialog::accept()
|
void AskPassphraseDialog::accept()
|
||||||
{
|
{
|
||||||
SecureString oldpass, newpass1, newpass2;
|
SecureString oldpass, newpass1, newpass2;
|
||||||
if(!model)
|
if (!model && mode != Encrypt)
|
||||||
return;
|
return;
|
||||||
oldpass.reserve(MAX_PASSPHRASE_SIZE);
|
oldpass.reserve(MAX_PASSPHRASE_SIZE);
|
||||||
newpass1.reserve(MAX_PASSPHRASE_SIZE);
|
newpass1.reserve(MAX_PASSPHRASE_SIZE);
|
||||||
@ -119,24 +120,33 @@ void AskPassphraseDialog::accept()
|
|||||||
{
|
{
|
||||||
if(newpass1 == newpass2)
|
if(newpass1 == newpass2)
|
||||||
{
|
{
|
||||||
if(model->setWalletEncrypted(true, newpass1))
|
QString encryption_reminder = tr("Remember that encrypting your wallet cannot fully protect "
|
||||||
{
|
"your bitcoins from being stolen by malware infecting your computer.");
|
||||||
QMessageBox::warning(this, tr("Wallet encrypted"),
|
if (m_passphrase_out) {
|
||||||
|
m_passphrase_out->assign(newpass1);
|
||||||
|
QMessageBox::warning(this, tr("Wallet to be encrypted"),
|
||||||
"<qt>" +
|
"<qt>" +
|
||||||
tr("Your wallet is now encrypted. "
|
tr("Your wallet is about to be encrypted. ") + encryption_reminder +
|
||||||
"Remember that encrypting your wallet cannot fully protect "
|
|
||||||
"your bitcoins from being stolen by malware infecting your computer.") +
|
|
||||||
"<br><br><b>" +
|
|
||||||
tr("IMPORTANT: Any previous backups you have made of your wallet file "
|
|
||||||
"should be replaced with the newly generated, encrypted wallet file. "
|
|
||||||
"For security reasons, previous backups of the unencrypted wallet file "
|
|
||||||
"will become useless as soon as you start using the new, encrypted wallet.") +
|
|
||||||
"</b></qt>");
|
"</b></qt>");
|
||||||
}
|
} else {
|
||||||
else
|
assert(model != nullptr);
|
||||||
{
|
if(model->setWalletEncrypted(true, newpass1))
|
||||||
QMessageBox::critical(this, tr("Wallet encryption failed"),
|
{
|
||||||
tr("Wallet encryption failed due to an internal error. Your wallet was not encrypted."));
|
QMessageBox::warning(this, tr("Wallet encrypted"),
|
||||||
|
"<qt>" +
|
||||||
|
tr("Your wallet is now encrypted. ") + encryption_reminder +
|
||||||
|
"<br><br><b>" +
|
||||||
|
tr("IMPORTANT: Any previous backups you have made of your wallet file "
|
||||||
|
"should be replaced with the newly generated, encrypted wallet file. "
|
||||||
|
"For security reasons, previous backups of the unencrypted wallet file "
|
||||||
|
"will become useless as soon as you start using the new, encrypted wallet.") +
|
||||||
|
"</b></qt>");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QMessageBox::critical(this, tr("Wallet encryption failed"),
|
||||||
|
tr("Wallet encryption failed due to an internal error. Your wallet was not encrypted."));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
QDialog::accept(); // Success
|
QDialog::accept(); // Success
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
|
|
||||||
|
#include <support/allocators/secure.h>
|
||||||
|
|
||||||
class WalletModel;
|
class WalletModel;
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
@ -27,7 +29,7 @@ public:
|
|||||||
Decrypt /**< Ask passphrase and decrypt wallet */
|
Decrypt /**< Ask passphrase and decrypt wallet */
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit AskPassphraseDialog(Mode mode, QWidget *parent);
|
explicit AskPassphraseDialog(Mode mode, QWidget *parent, SecureString* passphrase_out = nullptr);
|
||||||
~AskPassphraseDialog();
|
~AskPassphraseDialog();
|
||||||
|
|
||||||
void accept();
|
void accept();
|
||||||
@ -39,6 +41,7 @@ private:
|
|||||||
Mode mode;
|
Mode mode;
|
||||||
WalletModel *model;
|
WalletModel *model;
|
||||||
bool fCapsLock;
|
bool fCapsLock;
|
||||||
|
SecureString* m_passphrase_out;
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void textChanged();
|
void textChanged();
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include <qt/bitcoinunits.h>
|
#include <qt/bitcoinunits.h>
|
||||||
#include <qt/clientmodel.h>
|
#include <qt/clientmodel.h>
|
||||||
|
#include <qt/createwalletdialog.h>
|
||||||
#include <qt/guiconstants.h>
|
#include <qt/guiconstants.h>
|
||||||
#include <qt/guiutil.h>
|
#include <qt/guiutil.h>
|
||||||
#include <qt/modaloverlay.h>
|
#include <qt/modaloverlay.h>
|
||||||
@ -339,6 +340,9 @@ void BitcoinGUI::createActions()
|
|||||||
m_close_wallet_action = new QAction(tr("Close Wallet..."), this);
|
m_close_wallet_action = new QAction(tr("Close Wallet..."), this);
|
||||||
m_close_wallet_action->setStatusTip(tr("Close wallet"));
|
m_close_wallet_action->setStatusTip(tr("Close wallet"));
|
||||||
|
|
||||||
|
m_create_wallet_action = new QAction(tr("Create Wallet..."), this);
|
||||||
|
m_create_wallet_action->setStatusTip(tr("Create a new wallet"));
|
||||||
|
|
||||||
showHelpMessageAction = new QAction(tr("&Command-line options"), this);
|
showHelpMessageAction = new QAction(tr("&Command-line options"), this);
|
||||||
showHelpMessageAction->setMenuRole(QAction::NoRole);
|
showHelpMessageAction->setMenuRole(QAction::NoRole);
|
||||||
showHelpMessageAction->setStatusTip(tr("Show the %1 help message to get a list with possible Bitcoin command-line options").arg(PACKAGE_NAME));
|
showHelpMessageAction->setStatusTip(tr("Show the %1 help message to get a list with possible Bitcoin command-line options").arg(PACKAGE_NAME));
|
||||||
@ -379,31 +383,11 @@ void BitcoinGUI::createActions()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(action, &QAction::triggered, [this, name, path] {
|
connect(action, &QAction::triggered, [this, path] {
|
||||||
OpenWalletActivity* activity = m_wallet_controller->openWallet(path);
|
auto activity = new OpenWalletActivity(m_wallet_controller, this);
|
||||||
|
|
||||||
QProgressDialog* dialog = new QProgressDialog(this);
|
|
||||||
dialog->setLabelText(tr("Opening Wallet <b>%1</b>...").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::opened, this, &BitcoinGUI::setCurrentWallet);
|
||||||
connect(activity, &OpenWalletActivity::finished, activity, &QObject::deleteLater);
|
connect(activity, &OpenWalletActivity::finished, activity, &QObject::deleteLater);
|
||||||
connect(activity, &OpenWalletActivity::finished, dialog, &QObject::deleteLater);
|
activity->open(path);
|
||||||
bool invoked = QMetaObject::invokeMethod(activity, "open");
|
|
||||||
assert(invoked);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (m_open_wallet_menu->isEmpty()) {
|
if (m_open_wallet_menu->isEmpty()) {
|
||||||
@ -414,6 +398,12 @@ void BitcoinGUI::createActions()
|
|||||||
connect(m_close_wallet_action, &QAction::triggered, [this] {
|
connect(m_close_wallet_action, &QAction::triggered, [this] {
|
||||||
m_wallet_controller->closeWallet(walletFrame->currentWalletModel(), this);
|
m_wallet_controller->closeWallet(walletFrame->currentWalletModel(), this);
|
||||||
});
|
});
|
||||||
|
connect(m_create_wallet_action, &QAction::triggered, [this] {
|
||||||
|
auto activity = new CreateWalletActivity(m_wallet_controller, this);
|
||||||
|
connect(activity, &CreateWalletActivity::created, this, &BitcoinGUI::setCurrentWallet);
|
||||||
|
connect(activity, &CreateWalletActivity::finished, activity, &QObject::deleteLater);
|
||||||
|
activity->create();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
#endif // ENABLE_WALLET
|
#endif // ENABLE_WALLET
|
||||||
|
|
||||||
@ -435,6 +425,7 @@ void BitcoinGUI::createMenuBar()
|
|||||||
QMenu *file = appMenuBar->addMenu(tr("&File"));
|
QMenu *file = appMenuBar->addMenu(tr("&File"));
|
||||||
if(walletFrame)
|
if(walletFrame)
|
||||||
{
|
{
|
||||||
|
file->addAction(m_create_wallet_action);
|
||||||
file->addAction(m_open_wallet_action);
|
file->addAction(m_open_wallet_action);
|
||||||
file->addAction(m_close_wallet_action);
|
file->addAction(m_close_wallet_action);
|
||||||
file->addSeparator();
|
file->addSeparator();
|
||||||
|
@ -147,6 +147,7 @@ private:
|
|||||||
QAction* openRPCConsoleAction = nullptr;
|
QAction* openRPCConsoleAction = nullptr;
|
||||||
QAction* openAction = nullptr;
|
QAction* openAction = nullptr;
|
||||||
QAction* showHelpMessageAction = nullptr;
|
QAction* showHelpMessageAction = nullptr;
|
||||||
|
QAction* m_create_wallet_action{nullptr};
|
||||||
QAction* m_open_wallet_action{nullptr};
|
QAction* m_open_wallet_action{nullptr};
|
||||||
QMenu* m_open_wallet_menu{nullptr};
|
QMenu* m_open_wallet_menu{nullptr};
|
||||||
QAction* m_close_wallet_action{nullptr};
|
QAction* m_close_wallet_action{nullptr};
|
||||||
|
61
src/qt/createwalletdialog.cpp
Normal file
61
src/qt/createwalletdialog.cpp
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
#if defined(HAVE_CONFIG_H)
|
||||||
|
#include <config/bitcoin-config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <qt/createwalletdialog.h>
|
||||||
|
#include <qt/forms/ui_createwalletdialog.h>
|
||||||
|
|
||||||
|
#include <QPushButton>
|
||||||
|
|
||||||
|
CreateWalletDialog::CreateWalletDialog(QWidget* parent) :
|
||||||
|
QDialog(parent),
|
||||||
|
ui(new Ui::CreateWalletDialog)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
ui->buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Create"));
|
||||||
|
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
|
||||||
|
ui->wallet_name_line_edit->setFocus(Qt::ActiveWindowFocusReason);
|
||||||
|
|
||||||
|
connect(ui->wallet_name_line_edit, &QLineEdit::textEdited, [this](const QString& text) {
|
||||||
|
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!text.isEmpty());
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(ui->encrypt_wallet_checkbox, &QCheckBox::toggled, [this](bool checked) {
|
||||||
|
// Disable disable_privkeys_checkbox when encrypt is set to true, enable it when encrypt is false
|
||||||
|
ui->disable_privkeys_checkbox->setEnabled(!checked);
|
||||||
|
|
||||||
|
// When the disable_privkeys_checkbox is disabled, uncheck it.
|
||||||
|
if (!ui->disable_privkeys_checkbox->isEnabled()) {
|
||||||
|
ui->disable_privkeys_checkbox->setChecked(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
CreateWalletDialog::~CreateWalletDialog()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString CreateWalletDialog::walletName() const
|
||||||
|
{
|
||||||
|
return ui->wallet_name_line_edit->text();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CreateWalletDialog::encrypt() const
|
||||||
|
{
|
||||||
|
return ui->encrypt_wallet_checkbox->isChecked();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CreateWalletDialog::disablePrivateKeys() const
|
||||||
|
{
|
||||||
|
return ui->disable_privkeys_checkbox->isChecked();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CreateWalletDialog::blank() const
|
||||||
|
{
|
||||||
|
return ui->blank_wallet_checkbox->isChecked();
|
||||||
|
}
|
35
src/qt/createwalletdialog.h
Normal file
35
src/qt/createwalletdialog.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
// 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_CREATEWALLETDIALOG_H
|
||||||
|
#define BITCOIN_QT_CREATEWALLETDIALOG_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
|
||||||
|
class WalletModel;
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class CreateWalletDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Dialog for creating wallets
|
||||||
|
*/
|
||||||
|
class CreateWalletDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit CreateWalletDialog(QWidget* parent);
|
||||||
|
virtual ~CreateWalletDialog();
|
||||||
|
|
||||||
|
QString walletName() const;
|
||||||
|
bool encrypt() const;
|
||||||
|
bool disablePrivateKeys() const;
|
||||||
|
bool blank() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::CreateWalletDialog *ui;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // BITCOIN_QT_CREATEWALLETDIALOG_H
|
151
src/qt/forms/createwalletdialog.ui
Normal file
151
src/qt/forms/createwalletdialog.ui
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>CreateWalletDialog</class>
|
||||||
|
<widget class="QDialog" name="CreateWalletDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>364</width>
|
||||||
|
<height>185</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Create Wallet</string>
|
||||||
|
</property>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>10</x>
|
||||||
|
<y>140</y>
|
||||||
|
<width>341</width>
|
||||||
|
<height>32</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QLineEdit" name="wallet_name_line_edit">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>120</x>
|
||||||
|
<y>20</y>
|
||||||
|
<width>231</width>
|
||||||
|
<height>24</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>20</x>
|
||||||
|
<y>20</y>
|
||||||
|
<width>101</width>
|
||||||
|
<height>21</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Wallet Name</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QCheckBox" name="encrypt_wallet_checkbox">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>20</x>
|
||||||
|
<y>50</y>
|
||||||
|
<width>171</width>
|
||||||
|
<height>22</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Encrypt the wallet. The wallet will be encrypted with a password of your choice.</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Encrypt Wallet</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QCheckBox" name="disable_privkeys_checkbox">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>20</x>
|
||||||
|
<y>80</y>
|
||||||
|
<width>171</width>
|
||||||
|
<height>22</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Disable private keys for this wallet. Wallets with private keys disabled will have no private keys and cannot have an HD seed or imported private keys. This is ideal for watch-only wallets.</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Disable Private Keys</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QCheckBox" name="blank_wallet_checkbox">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>20</x>
|
||||||
|
<y>110</y>
|
||||||
|
<width>171</width>
|
||||||
|
<height>22</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Make a blank wallet. Blank wallets do not initially have private keys or scripts. Private keys and addresses can be imported, or an HD seed can be set, at a later time.</string>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Make Blank Wallet</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
<tabstops>
|
||||||
|
<tabstop>wallet_name_line_edit</tabstop>
|
||||||
|
<tabstop>encrypt_wallet_checkbox</tabstop>
|
||||||
|
<tabstop>disable_privkeys_checkbox</tabstop>
|
||||||
|
<tabstop>blank_wallet_checkbox</tabstop>
|
||||||
|
</tabstops>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>CreateWalletDialog</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>248</x>
|
||||||
|
<y>254</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>157</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>rejected()</signal>
|
||||||
|
<receiver>CreateWalletDialog</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>316</x>
|
||||||
|
<y>260</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>286</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
@ -5,6 +5,8 @@
|
|||||||
#ifndef BITCOIN_QT_GUICONSTANTS_H
|
#ifndef BITCOIN_QT_GUICONSTANTS_H
|
||||||
#define BITCOIN_QT_GUICONSTANTS_H
|
#define BITCOIN_QT_GUICONSTANTS_H
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
/* Milliseconds between model updates */
|
/* Milliseconds between model updates */
|
||||||
static const int MODEL_UPDATE_DELAY = 250;
|
static const int MODEL_UPDATE_DELAY = 250;
|
||||||
|
|
||||||
|
@ -2,8 +2,14 @@
|
|||||||
// Distributed under the MIT software license, see the accompanying
|
// Distributed under the MIT software license, see the accompanying
|
||||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#include <qt/askpassphrasedialog.h>
|
||||||
|
#include <qt/createwalletdialog.h>
|
||||||
|
#include <qt/guiconstants.h>
|
||||||
|
#include <qt/guiutil.h>
|
||||||
#include <qt/walletcontroller.h>
|
#include <qt/walletcontroller.h>
|
||||||
|
|
||||||
|
#include <wallet/wallet.h>
|
||||||
|
|
||||||
#include <interfaces/handler.h>
|
#include <interfaces/handler.h>
|
||||||
#include <interfaces/node.h>
|
#include <interfaces/node.h>
|
||||||
|
|
||||||
@ -13,10 +19,13 @@
|
|||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QMutexLocker>
|
#include <QMutexLocker>
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
|
#include <QTimer>
|
||||||
#include <QWindow>
|
#include <QWindow>
|
||||||
|
|
||||||
WalletController::WalletController(interfaces::Node& node, const PlatformStyle* platform_style, OptionsModel* options_model, QObject* parent)
|
WalletController::WalletController(interfaces::Node& node, const PlatformStyle* platform_style, OptionsModel* options_model, QObject* parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
|
, m_activity_thread(new QThread(this))
|
||||||
|
, m_activity_worker(new QObject)
|
||||||
, m_node(node)
|
, m_node(node)
|
||||||
, m_platform_style(platform_style)
|
, m_platform_style(platform_style)
|
||||||
, m_options_model(options_model)
|
, m_options_model(options_model)
|
||||||
@ -29,15 +38,17 @@ WalletController::WalletController(interfaces::Node& node, const PlatformStyle*
|
|||||||
getOrCreateWallet(std::move(wallet));
|
getOrCreateWallet(std::move(wallet));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_activity_thread.start();
|
m_activity_worker->moveToThread(m_activity_thread);
|
||||||
|
m_activity_thread->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not using the default destructor because not all member types definitions are
|
// Not using the default destructor because not all member types definitions are
|
||||||
// available in the header, just forward declared.
|
// available in the header, just forward declared.
|
||||||
WalletController::~WalletController()
|
WalletController::~WalletController()
|
||||||
{
|
{
|
||||||
m_activity_thread.quit();
|
m_activity_thread->quit();
|
||||||
m_activity_thread.wait();
|
m_activity_thread->wait();
|
||||||
|
delete m_activity_worker;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<WalletModel*> WalletController::getOpenWallets() const
|
std::vector<WalletModel*> WalletController::getOpenWallets() const
|
||||||
@ -60,13 +71,6 @@ std::map<std::string, bool> WalletController::listWalletDir() const
|
|||||||
return wallets;
|
return wallets;
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenWalletActivity* WalletController::openWallet(const std::string& name, QWidget* parent)
|
|
||||||
{
|
|
||||||
OpenWalletActivity* activity = new OpenWalletActivity(this, name);
|
|
||||||
activity->moveToThread(&m_activity_thread);
|
|
||||||
return activity;
|
|
||||||
}
|
|
||||||
|
|
||||||
void WalletController::closeWallet(WalletModel* wallet_model, QWidget* parent)
|
void WalletController::closeWallet(WalletModel* wallet_model, QWidget* parent)
|
||||||
{
|
{
|
||||||
QMessageBox box(parent);
|
QMessageBox box(parent);
|
||||||
@ -140,23 +144,147 @@ void WalletController::removeAndDeleteWallet(WalletModel* wallet_model)
|
|||||||
delete wallet_model;
|
delete wallet_model;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WalletControllerActivity::WalletControllerActivity(WalletController* wallet_controller, QWidget* parent_widget)
|
||||||
OpenWalletActivity::OpenWalletActivity(WalletController* wallet_controller, const std::string& name)
|
: QObject(wallet_controller)
|
||||||
: m_wallet_controller(wallet_controller)
|
, m_wallet_controller(wallet_controller)
|
||||||
, m_name(name)
|
, m_parent_widget(parent_widget)
|
||||||
{}
|
|
||||||
|
|
||||||
void OpenWalletActivity::open()
|
|
||||||
{
|
{
|
||||||
std::string error, warning;
|
}
|
||||||
std::unique_ptr<interfaces::Wallet> wallet = m_wallet_controller->m_node.loadWallet(m_name, error, warning);
|
|
||||||
if (!warning.empty()) {
|
WalletControllerActivity::~WalletControllerActivity()
|
||||||
Q_EMIT message(QMessageBox::Warning, QString::fromStdString(warning));
|
{
|
||||||
|
delete m_progress_dialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletControllerActivity::showProgressDialog(const QString& label_text)
|
||||||
|
{
|
||||||
|
m_progress_dialog = new QProgressDialog(m_parent_widget);
|
||||||
|
|
||||||
|
m_progress_dialog->setLabelText(label_text);
|
||||||
|
m_progress_dialog->setRange(0, 0);
|
||||||
|
m_progress_dialog->setCancelButton(nullptr);
|
||||||
|
m_progress_dialog->setWindowModality(Qt::ApplicationModal);
|
||||||
|
GUIUtil::PolishProgressDialog(m_progress_dialog);
|
||||||
|
}
|
||||||
|
|
||||||
|
CreateWalletActivity::CreateWalletActivity(WalletController* wallet_controller, QWidget* parent_widget)
|
||||||
|
: WalletControllerActivity(wallet_controller, parent_widget)
|
||||||
|
{
|
||||||
|
m_passphrase.reserve(MAX_PASSPHRASE_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
CreateWalletActivity::~CreateWalletActivity()
|
||||||
|
{
|
||||||
|
delete m_create_wallet_dialog;
|
||||||
|
delete m_passphrase_dialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CreateWalletActivity::askPasshprase()
|
||||||
|
{
|
||||||
|
m_passphrase_dialog = new AskPassphraseDialog(AskPassphraseDialog::Encrypt, m_parent_widget, &m_passphrase);
|
||||||
|
m_passphrase_dialog->show();
|
||||||
|
|
||||||
|
connect(m_passphrase_dialog, &QObject::destroyed, [this] {
|
||||||
|
m_passphrase_dialog = nullptr;
|
||||||
|
});
|
||||||
|
connect(m_passphrase_dialog, &QDialog::accepted, [this] {
|
||||||
|
createWallet();
|
||||||
|
});
|
||||||
|
connect(m_passphrase_dialog, &QDialog::rejected, [this] {
|
||||||
|
Q_EMIT finished();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void CreateWalletActivity::createWallet()
|
||||||
|
{
|
||||||
|
showProgressDialog(tr("Creating Wallet <b>%1</b>...").arg(m_create_wallet_dialog->walletName().toHtmlEscaped()));
|
||||||
|
|
||||||
|
std::string name = m_create_wallet_dialog->walletName().toStdString();
|
||||||
|
uint64_t flags = 0;
|
||||||
|
if (m_create_wallet_dialog->disablePrivateKeys()) {
|
||||||
|
flags |= WALLET_FLAG_DISABLE_PRIVATE_KEYS;
|
||||||
}
|
}
|
||||||
if (wallet) {
|
if (m_create_wallet_dialog->blank()) {
|
||||||
Q_EMIT opened(m_wallet_controller->getOrCreateWallet(std::move(wallet)));
|
flags |= WALLET_FLAG_BLANK_WALLET;
|
||||||
} else {
|
|
||||||
Q_EMIT message(QMessageBox::Critical, QString::fromStdString(error));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QTimer::singleShot(500, worker(), [this, name, flags] {
|
||||||
|
std::unique_ptr<interfaces::Wallet> wallet;
|
||||||
|
WalletCreationStatus status = node().createWallet(m_passphrase, flags, name, m_error_message, m_warning_message, wallet);
|
||||||
|
|
||||||
|
if (status == WalletCreationStatus::SUCCESS) m_wallet_model = m_wallet_controller->getOrCreateWallet(std::move(wallet));
|
||||||
|
|
||||||
|
QTimer::singleShot(500, this, &CreateWalletActivity::finish);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void CreateWalletActivity::finish()
|
||||||
|
{
|
||||||
|
m_progress_dialog->hide();
|
||||||
|
|
||||||
|
if (!m_error_message.empty()) {
|
||||||
|
QMessageBox::critical(m_parent_widget, tr("Create wallet failed"), QString::fromStdString(m_error_message));
|
||||||
|
} else if (!m_warning_message.empty()) {
|
||||||
|
QMessageBox::warning(m_parent_widget, tr("Create wallet warning"), QString::fromStdString(m_warning_message));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_wallet_model) Q_EMIT created(m_wallet_model);
|
||||||
|
|
||||||
Q_EMIT finished();
|
Q_EMIT finished();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CreateWalletActivity::create()
|
||||||
|
{
|
||||||
|
m_create_wallet_dialog = new CreateWalletDialog(m_parent_widget);
|
||||||
|
m_create_wallet_dialog->setWindowModality(Qt::ApplicationModal);
|
||||||
|
m_create_wallet_dialog->show();
|
||||||
|
|
||||||
|
connect(m_create_wallet_dialog, &QObject::destroyed, [this] {
|
||||||
|
m_create_wallet_dialog = nullptr;
|
||||||
|
});
|
||||||
|
connect(m_create_wallet_dialog, &QDialog::rejected, [this] {
|
||||||
|
Q_EMIT finished();
|
||||||
|
});
|
||||||
|
connect(m_create_wallet_dialog, &QDialog::accepted, [this] {
|
||||||
|
if (m_create_wallet_dialog->encrypt()) {
|
||||||
|
askPasshprase();
|
||||||
|
} else {
|
||||||
|
createWallet();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
OpenWalletActivity::OpenWalletActivity(WalletController* wallet_controller, QWidget* parent_widget)
|
||||||
|
: WalletControllerActivity(wallet_controller, parent_widget)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenWalletActivity::finish()
|
||||||
|
{
|
||||||
|
m_progress_dialog->hide();
|
||||||
|
|
||||||
|
if (!m_error_message.empty()) {
|
||||||
|
QMessageBox::critical(m_parent_widget, tr("Open wallet failed"), QString::fromStdString(m_error_message));
|
||||||
|
} else if (!m_warning_message.empty()) {
|
||||||
|
QMessageBox::warning(m_parent_widget, tr("Open wallet warning"), QString::fromStdString(m_warning_message));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_wallet_model) Q_EMIT opened(m_wallet_model);
|
||||||
|
|
||||||
|
Q_EMIT finished();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenWalletActivity::open(const std::string& path)
|
||||||
|
{
|
||||||
|
QString name = path.empty() ? QString("["+tr("default wallet")+"]") : QString::fromStdString(path);
|
||||||
|
|
||||||
|
showProgressDialog(tr("Opening Wallet <b>%1</b>...").arg(name.toHtmlEscaped()));
|
||||||
|
|
||||||
|
QTimer::singleShot(0, worker(), [this, path] {
|
||||||
|
std::unique_ptr<interfaces::Wallet> wallet = node().loadWallet(path, m_error_message, m_warning_message);
|
||||||
|
|
||||||
|
if (wallet) m_wallet_model = m_wallet_controller->getOrCreateWallet(std::move(wallet));
|
||||||
|
|
||||||
|
QTimer::singleShot(0, this, &OpenWalletActivity::finish);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
@ -6,15 +6,20 @@
|
|||||||
#define BITCOIN_QT_WALLETCONTROLLER_H
|
#define BITCOIN_QT_WALLETCONTROLLER_H
|
||||||
|
|
||||||
#include <qt/walletmodel.h>
|
#include <qt/walletmodel.h>
|
||||||
|
#include <support/allocators/secure.h>
|
||||||
#include <sync.h>
|
#include <sync.h>
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QMutex>
|
#include <QMutex>
|
||||||
|
#include <QProgressDialog>
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
class OptionsModel;
|
class OptionsModel;
|
||||||
class PlatformStyle;
|
class PlatformStyle;
|
||||||
@ -24,7 +29,11 @@ class Handler;
|
|||||||
class Node;
|
class Node;
|
||||||
} // namespace interfaces
|
} // namespace interfaces
|
||||||
|
|
||||||
|
class AskPassphraseDialog;
|
||||||
|
class CreateWalletActivity;
|
||||||
|
class CreateWalletDialog;
|
||||||
class OpenWalletActivity;
|
class OpenWalletActivity;
|
||||||
|
class WalletControllerActivity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Controller between interfaces::Node, WalletModel instances and the GUI.
|
* Controller between interfaces::Node, WalletModel instances and the GUI.
|
||||||
@ -33,7 +42,6 @@ class WalletController : public QObject
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
WalletModel* getOrCreateWallet(std::unique_ptr<interfaces::Wallet> wallet);
|
|
||||||
void removeAndDeleteWallet(WalletModel* wallet_model);
|
void removeAndDeleteWallet(WalletModel* wallet_model);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -43,11 +51,12 @@ public:
|
|||||||
//! Returns wallet models currently open.
|
//! Returns wallet models currently open.
|
||||||
std::vector<WalletModel*> getOpenWallets() const;
|
std::vector<WalletModel*> getOpenWallets() const;
|
||||||
|
|
||||||
|
WalletModel* getOrCreateWallet(std::unique_ptr<interfaces::Wallet> wallet);
|
||||||
|
|
||||||
//! Returns all wallet names in the wallet dir mapped to whether the wallet
|
//! Returns all wallet names in the wallet dir mapped to whether the wallet
|
||||||
//! is loaded.
|
//! is loaded.
|
||||||
std::map<std::string, bool> listWalletDir() const;
|
std::map<std::string, bool> listWalletDir() const;
|
||||||
|
|
||||||
OpenWalletActivity* openWallet(const std::string& name, QWidget* parent = nullptr);
|
|
||||||
void closeWallet(WalletModel* wallet_model, QWidget* parent = nullptr);
|
void closeWallet(WalletModel* wallet_model, QWidget* parent = nullptr);
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
@ -57,7 +66,8 @@ Q_SIGNALS:
|
|||||||
void coinsSent(WalletModel* wallet_model, SendCoinsRecipient recipient, QByteArray transaction);
|
void coinsSent(WalletModel* wallet_model, SendCoinsRecipient recipient, QByteArray transaction);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QThread m_activity_thread;
|
QThread* const m_activity_thread;
|
||||||
|
QObject* const m_activity_worker;
|
||||||
interfaces::Node& m_node;
|
interfaces::Node& m_node;
|
||||||
const PlatformStyle* const m_platform_style;
|
const PlatformStyle* const m_platform_style;
|
||||||
OptionsModel* const m_options_model;
|
OptionsModel* const m_options_model;
|
||||||
@ -65,27 +75,72 @@ private:
|
|||||||
std::vector<WalletModel*> m_wallets;
|
std::vector<WalletModel*> m_wallets;
|
||||||
std::unique_ptr<interfaces::Handler> m_handler_load_wallet;
|
std::unique_ptr<interfaces::Handler> m_handler_load_wallet;
|
||||||
|
|
||||||
friend class OpenWalletActivity;
|
friend class WalletControllerActivity;
|
||||||
};
|
};
|
||||||
|
|
||||||
class OpenWalletActivity : public QObject
|
class WalletControllerActivity : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
OpenWalletActivity(WalletController* wallet_controller, const std::string& name);
|
WalletControllerActivity(WalletController* wallet_controller, QWidget* parent_widget);
|
||||||
|
virtual ~WalletControllerActivity();
|
||||||
public Q_SLOTS:
|
|
||||||
void open();
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void message(QMessageBox::Icon icon, const QString text);
|
|
||||||
void finished();
|
void finished();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
interfaces::Node& node() const { return m_wallet_controller->m_node; }
|
||||||
|
QObject* worker() const { return m_wallet_controller->m_activity_worker; }
|
||||||
|
|
||||||
|
void showProgressDialog(const QString& label_text);
|
||||||
|
|
||||||
|
WalletController* const m_wallet_controller;
|
||||||
|
QWidget* const m_parent_widget;
|
||||||
|
QProgressDialog* m_progress_dialog{nullptr};
|
||||||
|
WalletModel* m_wallet_model{nullptr};
|
||||||
|
std::string m_error_message;
|
||||||
|
std::string m_warning_message;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class CreateWalletActivity : public WalletControllerActivity
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
CreateWalletActivity(WalletController* wallet_controller, QWidget* parent_widget);
|
||||||
|
virtual ~CreateWalletActivity();
|
||||||
|
|
||||||
|
void create();
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void created(WalletModel* wallet_model);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void askPasshprase();
|
||||||
|
void createWallet();
|
||||||
|
void finish();
|
||||||
|
|
||||||
|
SecureString m_passphrase;
|
||||||
|
CreateWalletDialog* m_create_wallet_dialog{nullptr};
|
||||||
|
AskPassphraseDialog* m_passphrase_dialog{nullptr};
|
||||||
|
};
|
||||||
|
|
||||||
|
class OpenWalletActivity : public WalletControllerActivity
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
OpenWalletActivity(WalletController* wallet_controller, QWidget* parent_widget);
|
||||||
|
|
||||||
|
void open(const std::string& path);
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
void opened(WalletModel* wallet_model);
|
void opened(WalletModel* wallet_model);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
WalletController* const m_wallet_controller;
|
void finish();
|
||||||
std::string const m_name;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // BITCOIN_QT_WALLETCONTROLLER_H
|
#endif // BITCOIN_QT_WALLETCONTROLLER_H
|
||||||
|
Loading…
Reference in New Issue
Block a user