ui: Support wallets unloaded dynamically
This commit is contained in:
parent
9f9b50d5fe
commit
0ee77b2077
9 changed files with 80 additions and 8 deletions
|
@ -429,6 +429,10 @@ public:
|
||||||
bool hdEnabled() override { return m_wallet.IsHDEnabled(); }
|
bool hdEnabled() override { return m_wallet.IsHDEnabled(); }
|
||||||
OutputType getDefaultAddressType() override { return m_wallet.m_default_address_type; }
|
OutputType getDefaultAddressType() override { return m_wallet.m_default_address_type; }
|
||||||
OutputType getDefaultChangeType() override { return m_wallet.m_default_change_type; }
|
OutputType getDefaultChangeType() override { return m_wallet.m_default_change_type; }
|
||||||
|
std::unique_ptr<Handler> handleUnload(UnloadFn fn) override
|
||||||
|
{
|
||||||
|
return MakeHandler(m_wallet.NotifyUnload.connect(fn));
|
||||||
|
}
|
||||||
std::unique_ptr<Handler> handleShowProgress(ShowProgressFn fn) override
|
std::unique_ptr<Handler> handleShowProgress(ShowProgressFn fn) override
|
||||||
{
|
{
|
||||||
return MakeHandler(m_wallet.ShowProgress.connect(fn));
|
return MakeHandler(m_wallet.ShowProgress.connect(fn));
|
||||||
|
|
|
@ -242,6 +242,10 @@ public:
|
||||||
// Get default change type.
|
// Get default change type.
|
||||||
virtual OutputType getDefaultChangeType() = 0;
|
virtual OutputType getDefaultChangeType() = 0;
|
||||||
|
|
||||||
|
//! Register handler for unload message.
|
||||||
|
using UnloadFn = std::function<void()>;
|
||||||
|
virtual std::unique_ptr<Handler> handleUnload(UnloadFn fn) = 0;
|
||||||
|
|
||||||
//! Register handler for show progress messages.
|
//! Register handler for show progress messages.
|
||||||
using ShowProgressFn = std::function<void(const std::string& title, int progress)>;
|
using ShowProgressFn = std::function<void(const std::string& title, int progress)>;
|
||||||
virtual std::unique_ptr<Handler> handleShowProgress(ShowProgressFn fn) = 0;
|
virtual std::unique_ptr<Handler> handleShowProgress(ShowProgressFn fn) = 0;
|
||||||
|
|
|
@ -238,6 +238,7 @@ public Q_SLOTS:
|
||||||
/// Handle runaway exceptions. Shows a message box with the problem and quits the program.
|
/// Handle runaway exceptions. Shows a message box with the problem and quits the program.
|
||||||
void handleRunawayException(const QString &message);
|
void handleRunawayException(const QString &message);
|
||||||
void addWallet(WalletModel* walletModel);
|
void addWallet(WalletModel* walletModel);
|
||||||
|
void removeWallet();
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void requestedInitialize();
|
void requestedInitialize();
|
||||||
|
@ -467,11 +468,22 @@ void BitcoinApplication::addWallet(WalletModel* walletModel)
|
||||||
|
|
||||||
connect(walletModel, SIGNAL(coinsSent(WalletModel*, SendCoinsRecipient, QByteArray)),
|
connect(walletModel, SIGNAL(coinsSent(WalletModel*, SendCoinsRecipient, QByteArray)),
|
||||||
paymentServer, SLOT(fetchPaymentACK(WalletModel*, const SendCoinsRecipient&, QByteArray)));
|
paymentServer, SLOT(fetchPaymentACK(WalletModel*, const SendCoinsRecipient&, QByteArray)));
|
||||||
|
connect(walletModel, SIGNAL(unload()), this, SLOT(removeWallet()));
|
||||||
|
|
||||||
m_wallet_models.push_back(walletModel);
|
m_wallet_models.push_back(walletModel);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BitcoinApplication::removeWallet()
|
||||||
|
{
|
||||||
|
#ifdef ENABLE_WALLET
|
||||||
|
WalletModel* walletModel = static_cast<WalletModel*>(sender());
|
||||||
|
m_wallet_models.erase(std::find(m_wallet_models.begin(), m_wallet_models.end(), walletModel));
|
||||||
|
window->removeWallet(walletModel);
|
||||||
|
walletModel->deleteLater();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void BitcoinApplication::initializeResult(bool success)
|
void BitcoinApplication::initializeResult(bool success)
|
||||||
{
|
{
|
||||||
qDebug() << __func__ << ": Initialization result: " << success;
|
qDebug() << __func__ << ": Initialization result: " << success;
|
||||||
|
@ -491,8 +503,10 @@ void BitcoinApplication::initializeResult(bool success)
|
||||||
|
|
||||||
#ifdef ENABLE_WALLET
|
#ifdef ENABLE_WALLET
|
||||||
m_handler_load_wallet = m_node.handleLoadWallet([this](std::unique_ptr<interfaces::Wallet> wallet) {
|
m_handler_load_wallet = m_node.handleLoadWallet([this](std::unique_ptr<interfaces::Wallet> wallet) {
|
||||||
QMetaObject::invokeMethod(this, "addWallet", Qt::QueuedConnection,
|
WalletModel* wallet_model = new WalletModel(std::move(wallet), m_node, platformStyle, optionsModel, nullptr);
|
||||||
Q_ARG(WalletModel*, new WalletModel(std::move(wallet), m_node, platformStyle, optionsModel)));
|
// Fix wallet model thread affinity.
|
||||||
|
wallet_model->moveToThread(thread());
|
||||||
|
QMetaObject::invokeMethod(this, "addWallet", Qt::QueuedConnection, Q_ARG(WalletModel*, wallet_model));
|
||||||
});
|
});
|
||||||
|
|
||||||
for (auto& wallet : m_node.getWallets()) {
|
for (auto& wallet : m_node.getWallets()) {
|
||||||
|
|
|
@ -120,6 +120,7 @@ BitcoinGUI::BitcoinGUI(interfaces::Node& node, const PlatformStyle *_platformSty
|
||||||
modalOverlay(0),
|
modalOverlay(0),
|
||||||
prevBlocks(0),
|
prevBlocks(0),
|
||||||
spinnerFrame(0),
|
spinnerFrame(0),
|
||||||
|
m_wallet_selector_label(nullptr),
|
||||||
platformStyle(_platformStyle)
|
platformStyle(_platformStyle)
|
||||||
{
|
{
|
||||||
QSettings settings;
|
QSettings settings;
|
||||||
|
@ -477,6 +478,16 @@ void BitcoinGUI::createToolBars()
|
||||||
|
|
||||||
m_wallet_selector = new QComboBox();
|
m_wallet_selector = new QComboBox();
|
||||||
connect(m_wallet_selector, SIGNAL(currentIndexChanged(int)), this, SLOT(setCurrentWalletBySelectorIndex(int)));
|
connect(m_wallet_selector, SIGNAL(currentIndexChanged(int)), this, SLOT(setCurrentWalletBySelectorIndex(int)));
|
||||||
|
|
||||||
|
m_wallet_selector_label = new QLabel();
|
||||||
|
m_wallet_selector_label->setText(tr("Wallet:") + " ");
|
||||||
|
m_wallet_selector_label->setBuddy(m_wallet_selector);
|
||||||
|
|
||||||
|
m_wallet_selector_label_action = appToolBar->addWidget(m_wallet_selector_label);
|
||||||
|
m_wallet_selector_action = appToolBar->addWidget(m_wallet_selector);
|
||||||
|
|
||||||
|
m_wallet_selector_label_action->setVisible(false);
|
||||||
|
m_wallet_selector_action->setVisible(false);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -556,16 +567,29 @@ bool BitcoinGUI::addWallet(WalletModel *walletModel)
|
||||||
setWalletActionsEnabled(true);
|
setWalletActionsEnabled(true);
|
||||||
m_wallet_selector->addItem(display_name, name);
|
m_wallet_selector->addItem(display_name, name);
|
||||||
if (m_wallet_selector->count() == 2) {
|
if (m_wallet_selector->count() == 2) {
|
||||||
m_wallet_selector_label = new QLabel();
|
m_wallet_selector_label_action->setVisible(true);
|
||||||
m_wallet_selector_label->setText(tr("Wallet:") + " ");
|
m_wallet_selector_action->setVisible(true);
|
||||||
m_wallet_selector_label->setBuddy(m_wallet_selector);
|
|
||||||
appToolBar->addWidget(m_wallet_selector_label);
|
|
||||||
appToolBar->addWidget(m_wallet_selector);
|
|
||||||
}
|
}
|
||||||
rpcConsole->addWallet(walletModel);
|
rpcConsole->addWallet(walletModel);
|
||||||
return walletFrame->addWallet(walletModel);
|
return walletFrame->addWallet(walletModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BitcoinGUI::removeWallet(WalletModel* walletModel)
|
||||||
|
{
|
||||||
|
if (!walletFrame) return false;
|
||||||
|
QString name = walletModel->getWalletName();
|
||||||
|
int index = m_wallet_selector->findData(name);
|
||||||
|
m_wallet_selector->removeItem(index);
|
||||||
|
if (m_wallet_selector->count() == 0) {
|
||||||
|
setWalletActionsEnabled(false);
|
||||||
|
} else if (m_wallet_selector->count() == 1) {
|
||||||
|
m_wallet_selector_label_action->setVisible(false);
|
||||||
|
m_wallet_selector_action->setVisible(false);
|
||||||
|
}
|
||||||
|
rpcConsole->removeWallet(walletModel);
|
||||||
|
return walletFrame->removeWallet(name);
|
||||||
|
}
|
||||||
|
|
||||||
bool BitcoinGUI::setCurrentWallet(const QString& name)
|
bool BitcoinGUI::setCurrentWallet(const QString& name)
|
||||||
{
|
{
|
||||||
if(!walletFrame)
|
if(!walletFrame)
|
||||||
|
|
|
@ -70,6 +70,7 @@ public:
|
||||||
functionality.
|
functionality.
|
||||||
*/
|
*/
|
||||||
bool addWallet(WalletModel *walletModel);
|
bool addWallet(WalletModel *walletModel);
|
||||||
|
bool removeWallet(WalletModel* walletModel);
|
||||||
void removeAllWallets();
|
void removeAllWallets();
|
||||||
#endif // ENABLE_WALLET
|
#endif // ENABLE_WALLET
|
||||||
bool enableWallet;
|
bool enableWallet;
|
||||||
|
@ -122,8 +123,10 @@ private:
|
||||||
QAction *openRPCConsoleAction;
|
QAction *openRPCConsoleAction;
|
||||||
QAction *openAction;
|
QAction *openAction;
|
||||||
QAction *showHelpMessageAction;
|
QAction *showHelpMessageAction;
|
||||||
|
QAction *m_wallet_selector_label_action = nullptr;
|
||||||
|
QAction *m_wallet_selector_action = nullptr;
|
||||||
|
|
||||||
QLabel *m_wallet_selector_label;
|
QLabel *m_wallet_selector_label = nullptr;
|
||||||
QComboBox *m_wallet_selector;
|
QComboBox *m_wallet_selector;
|
||||||
|
|
||||||
QSystemTrayIcon *trayIcon;
|
QSystemTrayIcon *trayIcon;
|
||||||
|
|
|
@ -713,6 +713,16 @@ void RPCConsole::addWallet(WalletModel * const walletModel)
|
||||||
ui->WalletSelectorLabel->setVisible(true);
|
ui->WalletSelectorLabel->setVisible(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RPCConsole::removeWallet(WalletModel * const walletModel)
|
||||||
|
{
|
||||||
|
const QString name = walletModel->getWalletName();
|
||||||
|
ui->WalletSelector->removeItem(ui->WalletSelector->findData(name));
|
||||||
|
if (ui->WalletSelector->count() == 2) {
|
||||||
|
ui->WalletSelector->setVisible(false);
|
||||||
|
ui->WalletSelectorLabel->setVisible(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static QString categoryClass(int category)
|
static QString categoryClass(int category)
|
||||||
|
|
|
@ -48,6 +48,7 @@ public:
|
||||||
|
|
||||||
void setClientModel(ClientModel *model);
|
void setClientModel(ClientModel *model);
|
||||||
void addWallet(WalletModel * const walletModel);
|
void addWallet(WalletModel * const walletModel);
|
||||||
|
void removeWallet(WalletModel* const walletModel);
|
||||||
|
|
||||||
enum MessageClass {
|
enum MessageClass {
|
||||||
MC_ERROR,
|
MC_ERROR,
|
||||||
|
|
|
@ -364,6 +364,12 @@ bool WalletModel::changePassphrase(const SecureString &oldPass, const SecureStri
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handlers for core signals
|
// Handlers for core signals
|
||||||
|
static void NotifyUnload(WalletModel* walletModel)
|
||||||
|
{
|
||||||
|
qDebug() << "NotifyUnload";
|
||||||
|
QMetaObject::invokeMethod(walletModel, "unload", Qt::QueuedConnection);
|
||||||
|
}
|
||||||
|
|
||||||
static void NotifyKeyStoreStatusChanged(WalletModel *walletmodel)
|
static void NotifyKeyStoreStatusChanged(WalletModel *walletmodel)
|
||||||
{
|
{
|
||||||
qDebug() << "NotifyKeyStoreStatusChanged";
|
qDebug() << "NotifyKeyStoreStatusChanged";
|
||||||
|
@ -411,6 +417,7 @@ static void NotifyWatchonlyChanged(WalletModel *walletmodel, bool fHaveWatchonly
|
||||||
void WalletModel::subscribeToCoreSignals()
|
void WalletModel::subscribeToCoreSignals()
|
||||||
{
|
{
|
||||||
// Connect signals to wallet
|
// Connect signals to wallet
|
||||||
|
m_handler_unload = m_wallet->handleUnload(boost::bind(&NotifyUnload, this));
|
||||||
m_handler_status_changed = m_wallet->handleStatusChanged(boost::bind(&NotifyKeyStoreStatusChanged, this));
|
m_handler_status_changed = m_wallet->handleStatusChanged(boost::bind(&NotifyKeyStoreStatusChanged, this));
|
||||||
m_handler_address_book_changed = m_wallet->handleAddressBookChanged(boost::bind(NotifyAddressBookChanged, this, _1, _2, _3, _4, _5));
|
m_handler_address_book_changed = m_wallet->handleAddressBookChanged(boost::bind(NotifyAddressBookChanged, this, _1, _2, _3, _4, _5));
|
||||||
m_handler_transaction_changed = m_wallet->handleTransactionChanged(boost::bind(NotifyTransactionChanged, this, _1, _2));
|
m_handler_transaction_changed = m_wallet->handleTransactionChanged(boost::bind(NotifyTransactionChanged, this, _1, _2));
|
||||||
|
@ -421,6 +428,7 @@ void WalletModel::subscribeToCoreSignals()
|
||||||
void WalletModel::unsubscribeFromCoreSignals()
|
void WalletModel::unsubscribeFromCoreSignals()
|
||||||
{
|
{
|
||||||
// Disconnect signals from wallet
|
// Disconnect signals from wallet
|
||||||
|
m_handler_unload->disconnect();
|
||||||
m_handler_status_changed->disconnect();
|
m_handler_status_changed->disconnect();
|
||||||
m_handler_address_book_changed->disconnect();
|
m_handler_address_book_changed->disconnect();
|
||||||
m_handler_transaction_changed->disconnect();
|
m_handler_transaction_changed->disconnect();
|
||||||
|
|
|
@ -208,6 +208,7 @@ public:
|
||||||
AddressTableModel* getAddressTableModel() const { return addressTableModel; }
|
AddressTableModel* getAddressTableModel() const { return addressTableModel; }
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<interfaces::Wallet> m_wallet;
|
std::unique_ptr<interfaces::Wallet> m_wallet;
|
||||||
|
std::unique_ptr<interfaces::Handler> m_handler_unload;
|
||||||
std::unique_ptr<interfaces::Handler> m_handler_status_changed;
|
std::unique_ptr<interfaces::Handler> m_handler_status_changed;
|
||||||
std::unique_ptr<interfaces::Handler> m_handler_address_book_changed;
|
std::unique_ptr<interfaces::Handler> m_handler_address_book_changed;
|
||||||
std::unique_ptr<interfaces::Handler> m_handler_transaction_changed;
|
std::unique_ptr<interfaces::Handler> m_handler_transaction_changed;
|
||||||
|
@ -261,6 +262,9 @@ Q_SIGNALS:
|
||||||
// Watch-only address added
|
// Watch-only address added
|
||||||
void notifyWatchonlyChanged(bool fHaveWatchonly);
|
void notifyWatchonlyChanged(bool fHaveWatchonly);
|
||||||
|
|
||||||
|
// Signal that wallet is about to be removed
|
||||||
|
void unload();
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
/* Wallet status might have changed */
|
/* Wallet status might have changed */
|
||||||
void updateStatus();
|
void updateStatus();
|
||||||
|
|
Loading…
Reference in a new issue