mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 03:52:49 +01:00
merge bitcoin#15450: Create wallet menu option
This commit is contained in:
parent
6fbedf7740
commit
0f90ea72d3
@ -19,7 +19,8 @@ FORMS += \
|
||||
../src/qt/forms/sendcoinsdialog.ui \
|
||||
../src/qt/forms/sendcoinsentry.ui \
|
||||
../src/qt/forms/signverifymessagedialog.ui \
|
||||
../src/qt/forms/transactiondescdialog.ui
|
||||
../src/qt/forms/transactiondescdialog.ui \
|
||||
../src/qt/forms/createwalletdialog.ui
|
||||
|
||||
RESOURCES += \
|
||||
../src/qt/dash.qrc
|
||||
|
@ -14,6 +14,7 @@ QT_FORMS_UI = \
|
||||
qt/forms/appearancewidget.ui \
|
||||
qt/forms/askpassphrasedialog.ui \
|
||||
qt/forms/coincontroldialog.ui \
|
||||
qt/forms/createwalletdialog.ui \
|
||||
qt/forms/editaddressdialog.ui \
|
||||
qt/forms/governancelist.ui \
|
||||
qt/forms/helpmessagedialog.ui \
|
||||
@ -37,6 +38,7 @@ QT_MOC_CPP = \
|
||||
qt/moc_addresstablemodel.cpp \
|
||||
qt/moc_appearancewidget.cpp \
|
||||
qt/moc_askpassphrasedialog.cpp \
|
||||
qt/moc_createwalletdialog.cpp \
|
||||
qt/moc_bantablemodel.cpp \
|
||||
qt/moc_bitcoinaddressvalidator.cpp \
|
||||
qt/moc_bitcoinamountfield.cpp \
|
||||
@ -125,6 +127,7 @@ BITCOIN_QT_H = \
|
||||
qt/clientmodel.h \
|
||||
qt/coincontroldialog.h \
|
||||
qt/coincontroltreewidget.h \
|
||||
qt/createwalletdialog.h \
|
||||
qt/csvmodelwriter.h \
|
||||
qt/dash.h \
|
||||
qt/editaddressdialog.h \
|
||||
@ -240,6 +243,7 @@ BITCOIN_QT_WALLET_CPP = \
|
||||
qt/askpassphrasedialog.cpp \
|
||||
qt/coincontroldialog.cpp \
|
||||
qt/coincontroltreewidget.cpp \
|
||||
qt/createwalletdialog.cpp \
|
||||
qt/editaddressdialog.cpp \
|
||||
qt/governancelist.cpp \
|
||||
qt/masternodelist.cpp \
|
||||
|
@ -5,8 +5,10 @@
|
||||
#include <logging.h>
|
||||
#include <util/system.h>
|
||||
#include <walletinitinterface.h>
|
||||
#include <support/allocators/secure.h>
|
||||
|
||||
class CWallet;
|
||||
enum class WalletCreationStatus;
|
||||
|
||||
namespace interfaces {
|
||||
class Chain;
|
||||
@ -91,6 +93,11 @@ std::shared_ptr<CWallet> LoadWallet(interfaces::Chain& chain, const std::string&
|
||||
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 {
|
||||
|
||||
class Wallet;
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <primitives/block.h>
|
||||
#include <rpc/server.h>
|
||||
#include <shutdown.h>
|
||||
#include <support/allocators/secure.h>
|
||||
#include <sync.h>
|
||||
#include <txmempool.h>
|
||||
#include <ui_interface.h>
|
||||
@ -49,6 +50,7 @@ fs::path GetWalletDir();
|
||||
std::vector<fs::path> ListWalletDir();
|
||||
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);
|
||||
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 {
|
||||
|
||||
@ -390,6 +392,13 @@ public:
|
||||
Masternode::Sync& masternodeSync() override { return m_masternodeSync; }
|
||||
CoinJoin::Options& coinJoinOptions() override { return m_coinjoin; }
|
||||
|
||||
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
|
||||
{
|
||||
return MakeHandler(::uiInterface.InitMessage_connect(fn));
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <net.h> // For CConnman::NumConnections
|
||||
#include <net_types.h> // For banmap_t
|
||||
#include <netaddress.h> // For Network
|
||||
#include <support/allocators/secure.h> // For SecureString
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
@ -29,6 +30,7 @@ class RPCTimerInterface;
|
||||
class UniValue;
|
||||
class proxyType;
|
||||
struct CNodeStateStats;
|
||||
enum class WalletCreationStatus;
|
||||
|
||||
namespace interfaces {
|
||||
class Handler;
|
||||
@ -279,6 +281,9 @@ public:
|
||||
//! Return interface for accessing coinjoin related handler.
|
||||
virtual CoinJoin::Options& coinJoinOptions() = 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.
|
||||
using InitMessageFn = std::function<void(const std::string& message)>;
|
||||
virtual std::unique_ptr<Handler> handleInitMessage(InitMessageFn fn) = 0;
|
||||
|
@ -20,12 +20,13 @@
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
|
||||
AskPassphraseDialog::AskPassphraseDialog(Mode _mode, QWidget *parent) :
|
||||
AskPassphraseDialog::AskPassphraseDialog(Mode _mode, QWidget *parent, SecureString* passphrase_out) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::AskPassphraseDialog),
|
||||
mode(_mode),
|
||||
model(nullptr),
|
||||
fCapsLock(false)
|
||||
fCapsLock(false),
|
||||
m_passphrase_out(passphrase_out)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
@ -106,7 +107,7 @@ void AskPassphraseDialog::setModel(WalletModel *_model)
|
||||
void AskPassphraseDialog::accept()
|
||||
{
|
||||
SecureString oldpass, newpass1, newpass2;
|
||||
if(!model)
|
||||
if (!model && mode != Encrypt)
|
||||
return;
|
||||
oldpass.reserve(MAX_PASSPHRASE_SIZE);
|
||||
newpass1.reserve(MAX_PASSPHRASE_SIZE);
|
||||
@ -135,14 +136,22 @@ void AskPassphraseDialog::accept()
|
||||
{
|
||||
if(newpass1 == newpass2)
|
||||
{
|
||||
QString encryption_reminder = tr("Remember that encrypting your wallet cannot fully protect "
|
||||
"your funds from being stolen by malware infecting your computer.");
|
||||
if (m_passphrase_out) {
|
||||
m_passphrase_out->assign(newpass1);
|
||||
QMessageBox::warning(this, tr("Wallet to be encrypted"),
|
||||
"<qt>" +
|
||||
tr("Your wallet is about to be encrypted. ") + encryption_reminder +
|
||||
"</b></qt>");
|
||||
} else {
|
||||
assert(model != nullptr);
|
||||
if(model->setWalletEncrypted(true, newpass1))
|
||||
{
|
||||
if (model->wallet().hdEnabled()) {
|
||||
QMessageBox::warning(this, tr("Wallet encrypted"),
|
||||
"<qt>" +
|
||||
tr("Your wallet is now encrypted. "
|
||||
"Remember that encrypting your wallet cannot fully protect "
|
||||
"your funds from being stolen by malware infecting your computer.") +
|
||||
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. "
|
||||
@ -152,9 +161,7 @@ void AskPassphraseDialog::accept()
|
||||
} else {
|
||||
QMessageBox::warning(this, tr("Wallet encrypted"),
|
||||
"<qt>" +
|
||||
tr("Your wallet is now encrypted. "
|
||||
"Remember that encrypting your wallet cannot fully protect "
|
||||
"your funds from being stolen by malware infecting your computer.") +
|
||||
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. "
|
||||
@ -168,6 +175,7 @@ void AskPassphraseDialog::accept()
|
||||
QMessageBox::critical(this, tr("Wallet encryption failed"),
|
||||
tr("Wallet encryption failed due to an internal error. Your wallet was not encrypted."));
|
||||
}
|
||||
}
|
||||
QDialog::accept(); // Success
|
||||
}
|
||||
else
|
||||
|
@ -7,6 +7,8 @@
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
#include <support/allocators/secure.h>
|
||||
|
||||
class WalletModel;
|
||||
|
||||
namespace Ui {
|
||||
@ -28,7 +30,7 @@ public:
|
||||
Decrypt /**< Ask passphrase and decrypt wallet */
|
||||
};
|
||||
|
||||
explicit AskPassphraseDialog(Mode mode, QWidget *parent);
|
||||
explicit AskPassphraseDialog(Mode mode, QWidget *parent, SecureString* passphrase_out = nullptr);
|
||||
~AskPassphraseDialog();
|
||||
|
||||
void accept() override;
|
||||
@ -40,6 +42,7 @@ private:
|
||||
Mode mode;
|
||||
WalletModel *model;
|
||||
bool fCapsLock;
|
||||
SecureString* m_passphrase_out;
|
||||
|
||||
private Q_SLOTS:
|
||||
void textChanged();
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include <qt/bitcoinunits.h>
|
||||
#include <qt/clientmodel.h>
|
||||
#include <qt/createwalletdialog.h>
|
||||
#include <qt/guiconstants.h>
|
||||
#include <qt/guiutil.h>
|
||||
#include <qt/modaloverlay.h>
|
||||
@ -436,6 +437,9 @@ void BitcoinGUI::createActions()
|
||||
m_close_wallet_action = new QAction(tr("Close Wallet..."), this);
|
||||
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->setMenuRole(QAction::NoRole);
|
||||
showHelpMessageAction->setStatusTip(tr("Show the %1 help message to get a list with possible Dash command-line options").arg(PACKAGE_NAME));
|
||||
@ -499,31 +503,11 @@ void BitcoinGUI::createActions()
|
||||
continue;
|
||||
}
|
||||
|
||||
connect(action, &QAction::triggered, [this, name, path] {
|
||||
OpenWalletActivity* activity = m_wallet_controller->openWallet(path);
|
||||
|
||||
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(action, &QAction::triggered, [this, path] {
|
||||
auto activity = new OpenWalletActivity(m_wallet_controller, this);
|
||||
connect(activity, &OpenWalletActivity::opened, this, &BitcoinGUI::setCurrentWallet);
|
||||
connect(activity, &OpenWalletActivity::finished, activity, &QObject::deleteLater);
|
||||
connect(activity, &OpenWalletActivity::finished, dialog, &QObject::deleteLater);
|
||||
bool invoked = QMetaObject::invokeMethod(activity, "open");
|
||||
assert(invoked);
|
||||
activity->open(path);
|
||||
});
|
||||
}
|
||||
if (m_open_wallet_menu->isEmpty()) {
|
||||
@ -534,6 +518,12 @@ void BitcoinGUI::createActions()
|
||||
connect(m_close_wallet_action, &QAction::triggered, [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
|
||||
|
||||
@ -558,6 +548,7 @@ void BitcoinGUI::createMenuBar()
|
||||
QMenu *file = appMenuBar->addMenu(tr("&File"));
|
||||
if(walletFrame)
|
||||
{
|
||||
file->addAction(m_create_wallet_action);
|
||||
file->addAction(m_open_wallet_action);
|
||||
file->addAction(m_close_wallet_action);
|
||||
file->addSeparator();
|
||||
|
@ -160,6 +160,7 @@ private:
|
||||
QAction* showBackupsAction = nullptr;
|
||||
QAction* openAction = nullptr;
|
||||
QAction* showHelpMessageAction = nullptr;
|
||||
QAction* m_create_wallet_action{nullptr};
|
||||
QAction* m_open_wallet_action{nullptr};
|
||||
QMenu* m_open_wallet_menu{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/dash-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>195</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>40</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>60</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>90</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>120</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>
|
@ -6,6 +6,8 @@
|
||||
#ifndef BITCOIN_QT_GUICONSTANTS_H
|
||||
#define BITCOIN_QT_GUICONSTANTS_H
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
/* Milliseconds between model updates */
|
||||
static const int MODEL_UPDATE_DELAY = 250;
|
||||
|
||||
|
@ -2,9 +2,14 @@
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// 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 <wallet/wallet.h>
|
||||
|
||||
#include <interfaces/handler.h>
|
||||
#include <interfaces/node.h>
|
||||
|
||||
@ -14,10 +19,13 @@
|
||||
#include <QMessageBox>
|
||||
#include <QMutexLocker>
|
||||
#include <QThread>
|
||||
#include <QTimer>
|
||||
#include <QWindow>
|
||||
|
||||
WalletController::WalletController(interfaces::Node& node, OptionsModel* options_model, QObject* parent)
|
||||
: QObject(parent)
|
||||
, m_activity_thread(new QThread(this))
|
||||
, m_activity_worker(new QObject)
|
||||
, m_node(node)
|
||||
, m_options_model(options_model)
|
||||
{
|
||||
@ -29,15 +37,17 @@ WalletController::WalletController(interfaces::Node& node, OptionsModel* options
|
||||
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
|
||||
// available in the header, just forward declared.
|
||||
WalletController::~WalletController()
|
||||
{
|
||||
m_activity_thread.quit();
|
||||
m_activity_thread.wait();
|
||||
m_activity_thread->quit();
|
||||
m_activity_thread->wait();
|
||||
delete m_activity_worker;
|
||||
}
|
||||
|
||||
std::vector<WalletModel*> WalletController::getOpenWallets() const
|
||||
@ -60,13 +70,6 @@ std::map<std::string, bool> WalletController::listWalletDir() const
|
||||
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)
|
||||
{
|
||||
QMessageBox box(parent);
|
||||
@ -146,23 +149,147 @@ void WalletController::removeAndDeleteWallet(WalletModel* wallet_model)
|
||||
delete wallet_model;
|
||||
}
|
||||
|
||||
|
||||
OpenWalletActivity::OpenWalletActivity(WalletController* wallet_controller, const std::string& name)
|
||||
: m_wallet_controller(wallet_controller)
|
||||
, m_name(name)
|
||||
{}
|
||||
|
||||
void OpenWalletActivity::open()
|
||||
WalletControllerActivity::WalletControllerActivity(WalletController* wallet_controller, QWidget* parent_widget)
|
||||
: QObject(wallet_controller)
|
||||
, m_wallet_controller(wallet_controller)
|
||||
, m_parent_widget(parent_widget)
|
||||
{
|
||||
std::string error, warning;
|
||||
std::unique_ptr<interfaces::Wallet> wallet = m_wallet_controller->m_node.loadWallet(m_name, error, warning);
|
||||
if (!warning.empty()) {
|
||||
Q_EMIT message(QMessageBox::Warning, QString::fromStdString(warning));
|
||||
}
|
||||
|
||||
WalletControllerActivity::~WalletControllerActivity()
|
||||
{
|
||||
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) {
|
||||
Q_EMIT opened(m_wallet_controller->getOrCreateWallet(std::move(wallet)));
|
||||
} else {
|
||||
Q_EMIT message(QMessageBox::Critical, QString::fromStdString(error));
|
||||
if (m_create_wallet_dialog->blank()) {
|
||||
flags |= WALLET_FLAG_BLANK_WALLET;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
#include <qt/walletmodel.h>
|
||||
#include <support/allocators/secure.h>
|
||||
#include <sync.h>
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <QMutex>
|
||||
#include <QProgressDialog>
|
||||
#include <QThread>
|
||||
#include <QTimer>
|
||||
#include <QString>
|
||||
|
||||
class OptionsModel;
|
||||
class PlatformStyle;
|
||||
@ -24,7 +29,11 @@ class Handler;
|
||||
class Node;
|
||||
} // namespace interfaces
|
||||
|
||||
class AskPassphraseDialog;
|
||||
class CreateWalletActivity;
|
||||
class CreateWalletDialog;
|
||||
class OpenWalletActivity;
|
||||
class WalletControllerActivity;
|
||||
|
||||
/**
|
||||
* Controller between interfaces::Node, WalletModel instances and the GUI.
|
||||
@ -33,7 +42,6 @@ class WalletController : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
WalletModel* getOrCreateWallet(std::unique_ptr<interfaces::Wallet> wallet);
|
||||
void removeAndDeleteWallet(WalletModel* wallet_model);
|
||||
|
||||
public:
|
||||
@ -43,11 +51,12 @@ public:
|
||||
//! Returns wallet models currently open.
|
||||
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
|
||||
//! is loaded.
|
||||
std::map<std::string, bool> listWalletDir() const;
|
||||
|
||||
OpenWalletActivity* openWallet(const std::string& name, QWidget* parent = nullptr);
|
||||
void closeWallet(WalletModel* wallet_model, QWidget* parent = nullptr);
|
||||
|
||||
Q_SIGNALS:
|
||||
@ -57,34 +66,80 @@ Q_SIGNALS:
|
||||
void coinsSent(WalletModel* wallet_model, SendCoinsRecipient recipient, QByteArray transaction);
|
||||
|
||||
private:
|
||||
QThread m_activity_thread;
|
||||
QThread* const m_activity_thread;
|
||||
QObject* const m_activity_worker;
|
||||
interfaces::Node& m_node;
|
||||
OptionsModel* const m_options_model;
|
||||
mutable QMutex m_mutex;
|
||||
std::vector<WalletModel*> m_wallets;
|
||||
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
|
||||
|
||||
public:
|
||||
OpenWalletActivity(WalletController* wallet_controller, const std::string& name);
|
||||
|
||||
public Q_SLOTS:
|
||||
void open();
|
||||
WalletControllerActivity(WalletController* wallet_controller, QWidget* parent_widget);
|
||||
virtual ~WalletControllerActivity();
|
||||
|
||||
Q_SIGNALS:
|
||||
void message(QMessageBox::Icon icon, const QString text);
|
||||
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);
|
||||
|
||||
private:
|
||||
WalletController* const m_wallet_controller;
|
||||
std::string const m_name;
|
||||
void finish();
|
||||
};
|
||||
|
||||
#endif // BITCOIN_QT_WALLETCONTROLLER_H
|
||||
|
Loading…
Reference in New Issue
Block a user