Merge #12610: Multiwallet for the GUI
779c5f984
Qt: hide RPCConsole wallet selector when no wallets are present (Jonas Schnelli)dc6f150f3
Qt: show wallet name in request dlg in case of multiwallet (Jonas Schnelli)4826ca4b8
Qt: show wallet name in send confirmation dlg in case of multiwallet (Jonas Schnelli)cfa4133ce
GUI: RPCConsole: Log wallet changes (Luke Dashjr)b6d04fc7c
Qt: Get wallet name from WalletModel rather than passing it around (Luke Dashjr)12d8d2681
Qt: When multiple wallets are used, include in notifications the name (Jonas Schnelli)d1ec34a76
Qt: QComboBox::setVisible doesn't work in toolbars, so defer adding it at all until needed (Luke Dashjr)d49cc70e6
Qt: Add wallet selector to debug console (Jonas Schnelli)d558f44c5
Bugfix: RPC: Add missing UnregisterHTTPHandler for /wallet/ (Luke Dashjr)85d531971
Qt: Ensure UI updates only come from the currently selected walletView (Luke Dashjr)e449f9a9e
Qt: Add a combobox to toolbar to select from multiple wallets (Luke Dashjr)3dba3c3ac
Qt: Load all wallets into WalletModels (Luke Dashjr) Pull request description: This is an overhaul of #11383 (plus some additions). It avoids unnecessary coupling of httpserver/jsonrpc and the wallet as well as it avoids pointer pure passing (and pointer deletion) of `CWallet` (plus other minor design changes). Additionally it adds the wallet name to the sendconfirmation and request dialog (in case multiwallet is active) Tree-SHA512: 3d06e18badbc5d1821e488bf1dae463bb0be544cf11b2b618e025812bfdd13c5f39604bb93b4c705313930e7dc4e66f4848b9469ba14871bade58e7a027246a1
This commit is contained in:
commit
25cf18f239
17 changed files with 209 additions and 63 deletions
|
@ -252,6 +252,9 @@ void StopHTTPRPC()
|
|||
{
|
||||
LogPrint(BCLog::RPC, "Stopping HTTP RPC server\n");
|
||||
UnregisterHTTPHandler("/", true);
|
||||
#ifdef ENABLE_WALLET
|
||||
UnregisterHTTPHandler("/wallet/", false);
|
||||
#endif
|
||||
if (httpRPCTimerInterface) {
|
||||
RPCUnsetTimerInterface(httpRPCTimerInterface.get());
|
||||
httpRPCTimerInterface.reset();
|
||||
|
|
|
@ -251,7 +251,7 @@ private:
|
|||
QTimer *pollShutdownTimer;
|
||||
#ifdef ENABLE_WALLET
|
||||
PaymentServer* paymentServer;
|
||||
WalletModel *walletModel;
|
||||
std::vector<WalletModel*> m_wallet_models;
|
||||
#endif
|
||||
int returnValue;
|
||||
const PlatformStyle *platformStyle;
|
||||
|
@ -333,7 +333,7 @@ BitcoinApplication::BitcoinApplication(int &argc, char **argv):
|
|||
pollShutdownTimer(0),
|
||||
#ifdef ENABLE_WALLET
|
||||
paymentServer(0),
|
||||
walletModel(0),
|
||||
m_wallet_models(),
|
||||
#endif
|
||||
returnValue(0)
|
||||
{
|
||||
|
@ -451,8 +451,10 @@ void BitcoinApplication::requestShutdown()
|
|||
|
||||
#ifdef ENABLE_WALLET
|
||||
window->removeAllWallets();
|
||||
for (WalletModel *walletModel : m_wallet_models) {
|
||||
delete walletModel;
|
||||
walletModel = 0;
|
||||
}
|
||||
m_wallet_models.clear();
|
||||
#endif
|
||||
delete clientModel;
|
||||
clientModel = 0;
|
||||
|
@ -481,16 +483,20 @@ void BitcoinApplication::initializeResult(bool success)
|
|||
window->setClientModel(clientModel);
|
||||
|
||||
#ifdef ENABLE_WALLET
|
||||
// TODO: Expose secondary wallets
|
||||
if (!vpwallets.empty())
|
||||
{
|
||||
walletModel = new WalletModel(platformStyle, vpwallets[0], optionsModel);
|
||||
bool fFirstWallet = true;
|
||||
for (CWalletRef pwallet : vpwallets) {
|
||||
WalletModel * const walletModel = new WalletModel(platformStyle, pwallet, optionsModel);
|
||||
|
||||
window->addWallet(BitcoinGUI::DEFAULT_WALLET, walletModel);
|
||||
window->setCurrentWallet(BitcoinGUI::DEFAULT_WALLET);
|
||||
window->addWallet(walletModel);
|
||||
if (fFirstWallet) {
|
||||
window->setCurrentWallet(walletModel->getWalletName());
|
||||
fFirstWallet = false;
|
||||
}
|
||||
|
||||
connect(walletModel, SIGNAL(coinsSent(CWallet*,SendCoinsRecipient,QByteArray)),
|
||||
paymentServer, SLOT(fetchPaymentACK(CWallet*,const SendCoinsRecipient&,QByteArray)));
|
||||
|
||||
m_wallet_models.push_back(walletModel);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#ifdef ENABLE_WALLET
|
||||
#include <qt/walletframe.h>
|
||||
#include <qt/walletmodel.h>
|
||||
#include <qt/walletview.h>
|
||||
#endif // ENABLE_WALLET
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
|
@ -36,6 +37,7 @@
|
|||
|
||||
#include <QAction>
|
||||
#include <QApplication>
|
||||
#include <QComboBox>
|
||||
#include <QDateTime>
|
||||
#include <QDesktopWidget>
|
||||
#include <QDragEnterEvent>
|
||||
|
@ -70,10 +72,6 @@ const std::string BitcoinGUI::DEFAULT_UIPLATFORM =
|
|||
#endif
|
||||
;
|
||||
|
||||
/** Display name for default wallet name. Uses tilde to avoid name
|
||||
* collisions in the future with additional wallets */
|
||||
const QString BitcoinGUI::DEFAULT_WALLET = "~Default";
|
||||
|
||||
BitcoinGUI::BitcoinGUI(const PlatformStyle *_platformStyle, const NetworkStyle *networkStyle, QWidget *parent) :
|
||||
QMainWindow(parent),
|
||||
enableWallet(false),
|
||||
|
@ -88,6 +86,7 @@ BitcoinGUI::BitcoinGUI(const PlatformStyle *_platformStyle, const NetworkStyle *
|
|||
progressBar(0),
|
||||
progressDialog(0),
|
||||
appMenuBar(0),
|
||||
appToolBar(0),
|
||||
overviewAction(0),
|
||||
historyAction(0),
|
||||
quitAction(0),
|
||||
|
@ -455,6 +454,7 @@ void BitcoinGUI::createToolBars()
|
|||
if(walletFrame)
|
||||
{
|
||||
QToolBar *toolbar = addToolBar(tr("Tabs toolbar"));
|
||||
appToolBar = toolbar;
|
||||
toolbar->setContextMenuPolicy(Qt::PreventContextMenu);
|
||||
toolbar->setMovable(false);
|
||||
toolbar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
|
||||
|
@ -463,6 +463,15 @@ void BitcoinGUI::createToolBars()
|
|||
toolbar->addAction(receiveCoinsAction);
|
||||
toolbar->addAction(historyAction);
|
||||
overviewAction->setChecked(true);
|
||||
|
||||
#ifdef ENABLE_WALLET
|
||||
QWidget *spacer = new QWidget();
|
||||
spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
toolbar->addWidget(spacer);
|
||||
|
||||
m_wallet_selector = new QComboBox();
|
||||
connect(m_wallet_selector, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(setCurrentWallet(const QString&)));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -529,12 +538,22 @@ void BitcoinGUI::setClientModel(ClientModel *_clientModel)
|
|||
}
|
||||
|
||||
#ifdef ENABLE_WALLET
|
||||
bool BitcoinGUI::addWallet(const QString& name, WalletModel *walletModel)
|
||||
bool BitcoinGUI::addWallet(WalletModel *walletModel)
|
||||
{
|
||||
if(!walletFrame)
|
||||
return false;
|
||||
const QString name = walletModel->getWalletName();
|
||||
setWalletActionsEnabled(true);
|
||||
return walletFrame->addWallet(name, walletModel);
|
||||
m_wallet_selector->addItem(name);
|
||||
if (m_wallet_selector->count() == 2) {
|
||||
m_wallet_selector_label = new QLabel();
|
||||
m_wallet_selector_label->setText(tr("Wallet:") + " ");
|
||||
m_wallet_selector_label->setBuddy(m_wallet_selector);
|
||||
appToolBar->addWidget(m_wallet_selector_label);
|
||||
appToolBar->addWidget(m_wallet_selector);
|
||||
}
|
||||
rpcConsole->addWallet(walletModel);
|
||||
return walletFrame->addWallet(walletModel);
|
||||
}
|
||||
|
||||
bool BitcoinGUI::setCurrentWallet(const QString& name)
|
||||
|
@ -983,12 +1002,15 @@ void BitcoinGUI::showEvent(QShowEvent *event)
|
|||
}
|
||||
|
||||
#ifdef ENABLE_WALLET
|
||||
void BitcoinGUI::incomingTransaction(const QString& date, int unit, const CAmount& amount, const QString& type, const QString& address, const QString& label)
|
||||
void BitcoinGUI::incomingTransaction(const QString& date, int unit, const CAmount& amount, const QString& type, const QString& address, const QString& label, const QString& walletName)
|
||||
{
|
||||
// On new transaction, make an info balloon
|
||||
QString msg = tr("Date: %1\n").arg(date) +
|
||||
tr("Amount: %1\n").arg(BitcoinUnits::formatWithUnit(unit, amount, true)) +
|
||||
tr("Type: %1\n").arg(type);
|
||||
tr("Amount: %1\n").arg(BitcoinUnits::formatWithUnit(unit, amount, true));
|
||||
if (WalletModel::isMultiwallet() && !walletName.isEmpty()) {
|
||||
msg += tr("Wallet: %1\n").arg(walletName);
|
||||
}
|
||||
msg += tr("Type: %1\n").arg(type);
|
||||
if (!label.isEmpty())
|
||||
msg += tr("Label: %1\n").arg(label);
|
||||
else if (!address.isEmpty())
|
||||
|
@ -1079,6 +1101,20 @@ void BitcoinGUI::setEncryptionStatus(int status)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void BitcoinGUI::updateWalletStatus()
|
||||
{
|
||||
if (!walletFrame) {
|
||||
return;
|
||||
}
|
||||
WalletView * const walletView = walletFrame->currentWalletView();
|
||||
if (!walletView) {
|
||||
return;
|
||||
}
|
||||
WalletModel * const walletModel = walletView->getWalletModel();
|
||||
setEncryptionStatus(walletModel->getEncryptionStatus());
|
||||
setHDStatus(walletModel->hdEnabled());
|
||||
}
|
||||
#endif // ENABLE_WALLET
|
||||
|
||||
void BitcoinGUI::showNormalIfMinimized(bool fToggleHidden)
|
||||
|
|
|
@ -33,6 +33,7 @@ class ModalOverlay;
|
|||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QAction;
|
||||
class QComboBox;
|
||||
class QProgressBar;
|
||||
class QProgressDialog;
|
||||
QT_END_NAMESPACE
|
||||
|
@ -46,7 +47,6 @@ class BitcoinGUI : public QMainWindow
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static const QString DEFAULT_WALLET;
|
||||
static const std::string DEFAULT_UIPLATFORM;
|
||||
|
||||
explicit BitcoinGUI(const PlatformStyle *platformStyle, const NetworkStyle *networkStyle, QWidget *parent = 0);
|
||||
|
@ -62,8 +62,7 @@ public:
|
|||
The wallet model represents a bitcoin wallet, and offers access to the list of transactions, address book and sending
|
||||
functionality.
|
||||
*/
|
||||
bool addWallet(const QString& name, WalletModel *walletModel);
|
||||
bool setCurrentWallet(const QString& name);
|
||||
bool addWallet(WalletModel *walletModel);
|
||||
void removeAllWallets();
|
||||
#endif // ENABLE_WALLET
|
||||
bool enableWallet;
|
||||
|
@ -90,6 +89,7 @@ private:
|
|||
QProgressDialog *progressDialog;
|
||||
|
||||
QMenuBar *appMenuBar;
|
||||
QToolBar *appToolBar;
|
||||
QAction *overviewAction;
|
||||
QAction *historyAction;
|
||||
QAction *quitAction;
|
||||
|
@ -112,6 +112,9 @@ private:
|
|||
QAction *openAction;
|
||||
QAction *showHelpMessageAction;
|
||||
|
||||
QLabel *m_wallet_selector_label;
|
||||
QComboBox *m_wallet_selector;
|
||||
|
||||
QSystemTrayIcon *trayIcon;
|
||||
QMenu *trayIconMenu;
|
||||
Notificator *notificator;
|
||||
|
@ -171,6 +174,12 @@ public Q_SLOTS:
|
|||
void message(const QString &title, const QString &message, unsigned int style, bool *ret = nullptr);
|
||||
|
||||
#ifdef ENABLE_WALLET
|
||||
bool setCurrentWallet(const QString& name);
|
||||
/** Set the UI status indicators based on the currently selected wallet.
|
||||
*/
|
||||
void updateWalletStatus();
|
||||
|
||||
private:
|
||||
/** Set the encryption status as shown in the UI.
|
||||
@param[in] status current encryption status
|
||||
@see WalletModel::EncryptionStatus
|
||||
|
@ -183,10 +192,11 @@ public Q_SLOTS:
|
|||
*/
|
||||
void setHDStatus(int hdEnabled);
|
||||
|
||||
public Q_SLOTS:
|
||||
bool handlePaymentRequest(const SendCoinsRecipient& recipient);
|
||||
|
||||
/** Show incoming transaction notification for new transactions. */
|
||||
void incomingTransaction(const QString& date, int unit, const CAmount& amount, const QString& type, const QString& address, const QString& label);
|
||||
void incomingTransaction(const QString& date, int unit, const CAmount& amount, const QString& type, const QString& address, const QString& label, const QString& walletName);
|
||||
#endif // ENABLE_WALLET
|
||||
|
||||
private Q_SLOTS:
|
||||
|
|
|
@ -412,6 +412,22 @@
|
|||
<property name="spacing">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="WalletSelectorLabel">
|
||||
<property name="text">
|
||||
<string>Wallet: </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="WalletSelector">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>(none)</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
|
|
|
@ -153,7 +153,7 @@ void ReceiveCoinsDialog::on_receiveButton_clicked()
|
|||
ui->reqAmount->value(), ui->reqMessage->text());
|
||||
ReceiveRequestDialog *dialog = new ReceiveRequestDialog(this);
|
||||
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||
dialog->setModel(model->getOptionsModel());
|
||||
dialog->setModel(model);
|
||||
dialog->setInfo(info);
|
||||
dialog->show();
|
||||
clear();
|
||||
|
@ -166,7 +166,7 @@ void ReceiveCoinsDialog::on_recentRequestsView_doubleClicked(const QModelIndex &
|
|||
{
|
||||
const RecentRequestsTableModel *submodel = model->getRecentRequestsTableModel();
|
||||
ReceiveRequestDialog *dialog = new ReceiveRequestDialog(this);
|
||||
dialog->setModel(model->getOptionsModel());
|
||||
dialog->setModel(model);
|
||||
dialog->setInfo(submodel->entry(index.row()).recipient);
|
||||
dialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||
dialog->show();
|
||||
|
|
|
@ -108,12 +108,12 @@ ReceiveRequestDialog::~ReceiveRequestDialog()
|
|||
delete ui;
|
||||
}
|
||||
|
||||
void ReceiveRequestDialog::setModel(OptionsModel *_model)
|
||||
void ReceiveRequestDialog::setModel(WalletModel *_model)
|
||||
{
|
||||
this->model = _model;
|
||||
|
||||
if (_model)
|
||||
connect(_model, SIGNAL(displayUnitChanged(int)), this, SLOT(update()));
|
||||
connect(_model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(update()));
|
||||
|
||||
// update the display unit if necessary
|
||||
update();
|
||||
|
@ -143,11 +143,14 @@ void ReceiveRequestDialog::update()
|
|||
html += "<a href=\""+uri+"\">" + GUIUtil::HtmlEscape(uri) + "</a><br>";
|
||||
html += "<b>"+tr("Address")+"</b>: " + GUIUtil::HtmlEscape(info.address) + "<br>";
|
||||
if(info.amount)
|
||||
html += "<b>"+tr("Amount")+"</b>: " + BitcoinUnits::formatHtmlWithUnit(model->getDisplayUnit(), info.amount) + "<br>";
|
||||
html += "<b>"+tr("Amount")+"</b>: " + BitcoinUnits::formatHtmlWithUnit(model->getOptionsModel()->getDisplayUnit(), info.amount) + "<br>";
|
||||
if(!info.label.isEmpty())
|
||||
html += "<b>"+tr("Label")+"</b>: " + GUIUtil::HtmlEscape(info.label) + "<br>";
|
||||
if(!info.message.isEmpty())
|
||||
html += "<b>"+tr("Message")+"</b>: " + GUIUtil::HtmlEscape(info.message) + "<br>";
|
||||
if(model->isMultiwallet()) {
|
||||
html += "<b>"+tr("Wallet")+"</b>: " + GUIUtil::HtmlEscape(model->getWalletName()) + "<br>";
|
||||
}
|
||||
ui->outUri->setText(html);
|
||||
|
||||
#ifdef USE_QRCODE
|
||||
|
|
|
@ -12,8 +12,6 @@
|
|||
#include <QLabel>
|
||||
#include <QPainter>
|
||||
|
||||
class OptionsModel;
|
||||
|
||||
namespace Ui {
|
||||
class ReceiveRequestDialog;
|
||||
}
|
||||
|
@ -53,7 +51,7 @@ public:
|
|||
explicit ReceiveRequestDialog(QWidget *parent = 0);
|
||||
~ReceiveRequestDialog();
|
||||
|
||||
void setModel(OptionsModel *model);
|
||||
void setModel(WalletModel *model);
|
||||
void setInfo(const SendCoinsRecipient &info);
|
||||
|
||||
private Q_SLOTS:
|
||||
|
@ -64,7 +62,7 @@ private Q_SLOTS:
|
|||
|
||||
private:
|
||||
Ui::ReceiveRequestDialog *ui;
|
||||
OptionsModel *model;
|
||||
WalletModel *model;
|
||||
SendCoinsRecipient info;
|
||||
};
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <qt/bantablemodel.h>
|
||||
#include <qt/clientmodel.h>
|
||||
#include <qt/platformstyle.h>
|
||||
#include <qt/walletmodel.h>
|
||||
#include <chainparams.h>
|
||||
#include <netbase.h>
|
||||
#include <rpc/server.h>
|
||||
|
@ -84,7 +85,7 @@ class RPCExecutor : public QObject
|
|||
Q_OBJECT
|
||||
|
||||
public Q_SLOTS:
|
||||
void request(const QString &command);
|
||||
void request(const QString &command, const QString &walletID);
|
||||
|
||||
Q_SIGNALS:
|
||||
void reply(int category, const QString &command);
|
||||
|
@ -145,7 +146,7 @@ public:
|
|||
* @param[out] pstrFilteredOut Command line, filtered to remove any sensitive data
|
||||
*/
|
||||
|
||||
bool RPCConsole::RPCParseCommandLine(std::string &strResult, const std::string &strCommand, const bool fExecute, std::string * const pstrFilteredOut)
|
||||
bool RPCConsole::RPCParseCommandLine(std::string &strResult, const std::string &strCommand, const bool fExecute, std::string * const pstrFilteredOut, const std::string *walletID)
|
||||
{
|
||||
std::vector< std::vector<std::string> > stack;
|
||||
stack.push_back(std::vector<std::string>());
|
||||
|
@ -303,10 +304,8 @@ bool RPCConsole::RPCParseCommandLine(std::string &strResult, const std::string &
|
|||
req.params = RPCConvertValues(stack.back()[0], std::vector<std::string>(stack.back().begin() + 1, stack.back().end()));
|
||||
req.strMethod = stack.back()[0];
|
||||
#ifdef ENABLE_WALLET
|
||||
// TODO: Move this logic to WalletModel
|
||||
if (!vpwallets.empty()) {
|
||||
// in Qt, use always the wallet with index 0 when running with multiple wallets
|
||||
QByteArray encodedName = QUrl::toPercentEncoding(QString::fromStdString(vpwallets[0]->GetName()));
|
||||
if (walletID && !walletID->empty()) {
|
||||
QByteArray encodedName = QUrl::toPercentEncoding(QString::fromStdString(*walletID));
|
||||
req.URI = "/wallet/"+std::string(encodedName.constData(), encodedName.length());
|
||||
}
|
||||
#endif
|
||||
|
@ -385,7 +384,7 @@ bool RPCConsole::RPCParseCommandLine(std::string &strResult, const std::string &
|
|||
}
|
||||
}
|
||||
|
||||
void RPCExecutor::request(const QString &command)
|
||||
void RPCExecutor::request(const QString &command, const QString &walletID)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -416,7 +415,8 @@ void RPCExecutor::request(const QString &command)
|
|||
" example: getblock(getblockhash(0),true)[tx][0]\n\n")));
|
||||
return;
|
||||
}
|
||||
if(!RPCConsole::RPCExecuteCommandLine(result, executableCommand))
|
||||
std::string wallet_id = walletID.toStdString();
|
||||
if(!RPCConsole::RPCExecuteCommandLine(result, executableCommand, nullptr, &wallet_id))
|
||||
{
|
||||
Q_EMIT reply(RPCConsole::CMD_ERROR, QString("Parse error: unbalanced ' or \""));
|
||||
return;
|
||||
|
@ -478,6 +478,10 @@ RPCConsole::RPCConsole(const PlatformStyle *_platformStyle, QWidget *parent) :
|
|||
connect(ui->fontSmallerButton, SIGNAL(clicked()), this, SLOT(fontSmaller()));
|
||||
connect(ui->btnClearTrafficGraph, SIGNAL(clicked()), ui->trafficGraph, SLOT(clear()));
|
||||
|
||||
// disable the wallet selector by default
|
||||
ui->WalletSelector->setVisible(false);
|
||||
ui->WalletSelectorLabel->setVisible(false);
|
||||
|
||||
// set library version labels
|
||||
#ifdef ENABLE_WALLET
|
||||
ui->berkeleyDBVersion->setText(DbEnv::version(0, 0, 0));
|
||||
|
@ -687,6 +691,23 @@ void RPCConsole::setClientModel(ClientModel *model)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef ENABLE_WALLET
|
||||
void RPCConsole::addWallet(WalletModel * const walletModel)
|
||||
{
|
||||
const QString name = walletModel->getWalletName();
|
||||
// use name for text and internal data object (to allow to move to a wallet id later)
|
||||
ui->WalletSelector->addItem(name, name);
|
||||
if (ui->WalletSelector->count() == 2 && !isVisible()) {
|
||||
// First wallet added, set to default so long as the window isn't presently visible (and potentially in use)
|
||||
ui->WalletSelector->setCurrentIndex(1);
|
||||
}
|
||||
if (ui->WalletSelector->count() > 2) {
|
||||
ui->WalletSelector->setVisible(true);
|
||||
ui->WalletSelectorLabel->setVisible(true);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static QString categoryClass(int category)
|
||||
{
|
||||
switch(category)
|
||||
|
@ -874,8 +895,25 @@ void RPCConsole::on_lineEdit_returnPressed()
|
|||
|
||||
cmdBeforeBrowsing = QString();
|
||||
|
||||
QString walletID;
|
||||
#ifdef ENABLE_WALLET
|
||||
const int wallet_index = ui->WalletSelector->currentIndex();
|
||||
if (wallet_index > 0) {
|
||||
walletID = (QString)ui->WalletSelector->itemData(wallet_index).value<QString>();
|
||||
}
|
||||
|
||||
if (m_last_wallet_id != walletID) {
|
||||
if (walletID.isEmpty()) {
|
||||
message(CMD_REQUEST, tr("Executing command without any wallet"));
|
||||
} else {
|
||||
message(CMD_REQUEST, tr("Executing command using \"%1\" wallet").arg(walletID));
|
||||
}
|
||||
m_last_wallet_id = walletID;
|
||||
}
|
||||
#endif
|
||||
|
||||
message(CMD_REQUEST, QString::fromStdString(strFilteredCmd));
|
||||
Q_EMIT cmdRequest(cmd);
|
||||
Q_EMIT cmdRequest(cmd, walletID);
|
||||
|
||||
cmd = QString::fromStdString(strFilteredCmd);
|
||||
|
||||
|
@ -923,7 +961,7 @@ void RPCConsole::startExecutor()
|
|||
// Replies from executor object must go to this object
|
||||
connect(executor, SIGNAL(reply(int,QString)), this, SLOT(message(int,QString)));
|
||||
// Requests from this object must go to executor
|
||||
connect(this, SIGNAL(cmdRequest(QString)), executor, SLOT(request(QString)));
|
||||
connect(this, SIGNAL(cmdRequest(QString, QString)), executor, SLOT(request(QString, QString)));
|
||||
|
||||
// On stopExecutor signal
|
||||
// - quit the Qt event loop in the execution thread
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
class ClientModel;
|
||||
class PlatformStyle;
|
||||
class RPCTimerInterface;
|
||||
class WalletModel;
|
||||
|
||||
namespace Ui {
|
||||
class RPCConsole;
|
||||
|
@ -36,12 +37,13 @@ public:
|
|||
explicit RPCConsole(const PlatformStyle *platformStyle, QWidget *parent);
|
||||
~RPCConsole();
|
||||
|
||||
static bool RPCParseCommandLine(std::string &strResult, const std::string &strCommand, bool fExecute, std::string * const pstrFilteredOut = nullptr);
|
||||
static bool RPCExecuteCommandLine(std::string &strResult, const std::string &strCommand, std::string * const pstrFilteredOut = nullptr) {
|
||||
return RPCParseCommandLine(strResult, strCommand, true, pstrFilteredOut);
|
||||
static bool RPCParseCommandLine(std::string &strResult, const std::string &strCommand, bool fExecute, std::string * const pstrFilteredOut = nullptr, const std::string *walletID = nullptr);
|
||||
static bool RPCExecuteCommandLine(std::string &strResult, const std::string &strCommand, std::string * const pstrFilteredOut = nullptr, const std::string *walletID = nullptr) {
|
||||
return RPCParseCommandLine(strResult, strCommand, true, pstrFilteredOut, walletID);
|
||||
}
|
||||
|
||||
void setClientModel(ClientModel *model);
|
||||
void addWallet(WalletModel * const walletModel);
|
||||
|
||||
enum MessageClass {
|
||||
MC_ERROR,
|
||||
|
@ -120,7 +122,7 @@ public Q_SLOTS:
|
|||
Q_SIGNALS:
|
||||
// For RPC command executor
|
||||
void stopExecutor();
|
||||
void cmdRequest(const QString &command);
|
||||
void cmdRequest(const QString &command, const QString &walletID);
|
||||
|
||||
private:
|
||||
void startExecutor();
|
||||
|
@ -151,6 +153,7 @@ private:
|
|||
int consoleFontSize;
|
||||
QCompleter *autoCompleter;
|
||||
QThread thread;
|
||||
QString m_last_wallet_id;
|
||||
|
||||
/** Update UI with latest network info from model. */
|
||||
void updateNetworkState();
|
||||
|
|
|
@ -277,8 +277,11 @@ void SendCoinsDialog::on_sendButton_clicked()
|
|||
QStringList formatted;
|
||||
for (const SendCoinsRecipient &rcp : currentTransaction.getRecipients())
|
||||
{
|
||||
// generate bold amount string
|
||||
// generate bold amount string with wallet name in case of multiwallet
|
||||
QString amount = "<b>" + BitcoinUnits::formatHtmlWithUnit(model->getOptionsModel()->getDisplayUnit(), rcp.amount);
|
||||
if (model->isMultiwallet()) {
|
||||
amount.append(" <u>"+tr("from wallet %1").arg(GUIUtil::HtmlEscape(model->getWalletName()))+"</u> ");
|
||||
}
|
||||
amount.append("</b>");
|
||||
// generate monospace address string
|
||||
QString address = "<span style='font-family: monospace;'>" + rcp.address;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <qt/walletframe.h>
|
||||
#include <qt/walletmodel.h>
|
||||
|
||||
#include <qt/bitcoingui.h>
|
||||
#include <qt/walletview.h>
|
||||
|
@ -39,10 +40,16 @@ void WalletFrame::setClientModel(ClientModel *_clientModel)
|
|||
this->clientModel = _clientModel;
|
||||
}
|
||||
|
||||
bool WalletFrame::addWallet(const QString& name, WalletModel *walletModel)
|
||||
bool WalletFrame::addWallet(WalletModel *walletModel)
|
||||
{
|
||||
if (!gui || !clientModel || !walletModel || mapWalletViews.count(name) > 0)
|
||||
if (!gui || !clientModel || !walletModel) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const QString name = walletModel->getWalletName();
|
||||
if (mapWalletViews.count(name) > 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
WalletView *walletView = new WalletView(platformStyle, this);
|
||||
walletView->setBitcoinGUI(gui);
|
||||
|
|
|
@ -36,7 +36,7 @@ public:
|
|||
|
||||
void setClientModel(ClientModel *clientModel);
|
||||
|
||||
bool addWallet(const QString& name, WalletModel *walletModel);
|
||||
bool addWallet(WalletModel *walletModel);
|
||||
bool setCurrentWallet(const QString& name);
|
||||
bool removeWallet(const QString &name);
|
||||
void removeAllWallets();
|
||||
|
@ -59,6 +59,7 @@ private:
|
|||
|
||||
const PlatformStyle *platformStyle;
|
||||
|
||||
public:
|
||||
WalletView *currentWalletView();
|
||||
|
||||
public Q_SLOTS:
|
||||
|
|
|
@ -110,8 +110,9 @@ void WalletModel::updateStatus()
|
|||
{
|
||||
EncryptionStatus newEncryptionStatus = getEncryptionStatus();
|
||||
|
||||
if(cachedEncryptionStatus != newEncryptionStatus)
|
||||
Q_EMIT encryptionStatusChanged(newEncryptionStatus);
|
||||
if(cachedEncryptionStatus != newEncryptionStatus) {
|
||||
Q_EMIT encryptionStatusChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void WalletModel::pollBalanceChanged()
|
||||
|
@ -743,3 +744,18 @@ int WalletModel::getDefaultConfirmTarget() const
|
|||
{
|
||||
return nTxConfirmTarget;
|
||||
}
|
||||
|
||||
QString WalletModel::getWalletName() const
|
||||
{
|
||||
LOCK(wallet->cs_wallet);
|
||||
QString walletName = QString::fromStdString(wallet->GetName());
|
||||
if (walletName.endsWith(".dat")) {
|
||||
walletName.truncate(walletName.size() - 4);
|
||||
}
|
||||
return walletName;
|
||||
}
|
||||
|
||||
bool WalletModel::isMultiwallet()
|
||||
{
|
||||
return gArgs.GetArgs("-wallet").size() > 1;
|
||||
}
|
||||
|
|
|
@ -136,6 +136,8 @@ public:
|
|||
TransactionTableModel *getTransactionTableModel();
|
||||
RecentRequestsTableModel *getRecentRequestsTableModel();
|
||||
|
||||
CWallet *getWallet() const { return wallet; };
|
||||
|
||||
CAmount getBalance(const CCoinControl *coinControl = nullptr) const;
|
||||
CAmount getUnconfirmedBalance() const;
|
||||
CAmount getImmatureBalance() const;
|
||||
|
@ -225,6 +227,9 @@ public:
|
|||
|
||||
int getDefaultConfirmTarget() const;
|
||||
|
||||
QString getWalletName() const;
|
||||
|
||||
static bool isMultiwallet();
|
||||
private:
|
||||
CWallet *wallet;
|
||||
bool fHaveWatchOnly;
|
||||
|
@ -260,7 +265,7 @@ Q_SIGNALS:
|
|||
const CAmount& watchOnlyBalance, const CAmount& watchUnconfBalance, const CAmount& watchImmatureBalance);
|
||||
|
||||
// Encryption status of wallet changed
|
||||
void encryptionStatusChanged(int status);
|
||||
void encryptionStatusChanged();
|
||||
|
||||
// Signal emitted when wallet needs to be unlocked
|
||||
// It is valid behaviour for listeners to keep the wallet locked after this signal;
|
||||
|
|
|
@ -101,13 +101,13 @@ void WalletView::setBitcoinGUI(BitcoinGUI *gui)
|
|||
connect(this, SIGNAL(message(QString,QString,unsigned int)), gui, SLOT(message(QString,QString,unsigned int)));
|
||||
|
||||
// Pass through encryption status changed signals
|
||||
connect(this, SIGNAL(encryptionStatusChanged(int)), gui, SLOT(setEncryptionStatus(int)));
|
||||
connect(this, SIGNAL(encryptionStatusChanged()), gui, SLOT(updateWalletStatus()));
|
||||
|
||||
// Pass through transaction notifications
|
||||
connect(this, SIGNAL(incomingTransaction(QString,int,CAmount,QString,QString,QString)), gui, SLOT(incomingTransaction(QString,int,CAmount,QString,QString,QString)));
|
||||
connect(this, SIGNAL(incomingTransaction(QString,int,CAmount,QString,QString,QString,QString)), gui, SLOT(incomingTransaction(QString,int,CAmount,QString,QString,QString,QString)));
|
||||
|
||||
// Connect HD enabled state signal
|
||||
connect(this, SIGNAL(hdEnabledStatusChanged(int)), gui, SLOT(setHDStatus(int)));
|
||||
connect(this, SIGNAL(hdEnabledStatusChanged()), gui, SLOT(updateWalletStatus()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -137,11 +137,11 @@ void WalletView::setWalletModel(WalletModel *_walletModel)
|
|||
connect(_walletModel, SIGNAL(message(QString,QString,unsigned int)), this, SIGNAL(message(QString,QString,unsigned int)));
|
||||
|
||||
// Handle changes in encryption status
|
||||
connect(_walletModel, SIGNAL(encryptionStatusChanged(int)), this, SIGNAL(encryptionStatusChanged(int)));
|
||||
connect(_walletModel, SIGNAL(encryptionStatusChanged()), this, SIGNAL(encryptionStatusChanged()));
|
||||
updateEncryptionStatus();
|
||||
|
||||
// update HD status
|
||||
Q_EMIT hdEnabledStatusChanged(_walletModel->hdEnabled());
|
||||
Q_EMIT hdEnabledStatusChanged();
|
||||
|
||||
// Balloon pop-up for new transaction
|
||||
connect(_walletModel->getTransactionTableModel(), SIGNAL(rowsInserted(QModelIndex,int,int)),
|
||||
|
@ -172,7 +172,7 @@ void WalletView::processNewTransaction(const QModelIndex& parent, int start, int
|
|||
QString address = ttm->data(index, TransactionTableModel::AddressRole).toString();
|
||||
QString label = ttm->data(index, TransactionTableModel::LabelRole).toString();
|
||||
|
||||
Q_EMIT incomingTransaction(date, walletModel->getOptionsModel()->getDisplayUnit(), amount, type, address, label);
|
||||
Q_EMIT incomingTransaction(date, walletModel->getOptionsModel()->getDisplayUnit(), amount, type, address, label, walletModel->getWalletName());
|
||||
}
|
||||
|
||||
void WalletView::gotoOverviewPage()
|
||||
|
@ -234,7 +234,7 @@ void WalletView::showOutOfSyncWarning(bool fShow)
|
|||
|
||||
void WalletView::updateEncryptionStatus()
|
||||
{
|
||||
Q_EMIT encryptionStatusChanged(walletModel->getEncryptionStatus());
|
||||
Q_EMIT encryptionStatusChanged();
|
||||
}
|
||||
|
||||
void WalletView::encryptWallet(bool status)
|
||||
|
|
|
@ -44,6 +44,7 @@ public:
|
|||
The client model represents the part of the core that communicates with the P2P network, and is wallet-agnostic.
|
||||
*/
|
||||
void setClientModel(ClientModel *clientModel);
|
||||
WalletModel *getWalletModel() { return walletModel; }
|
||||
/** Set the wallet model.
|
||||
The wallet model represents a bitcoin wallet, and offers access to the list of transactions, address book and sending
|
||||
functionality.
|
||||
|
@ -119,11 +120,11 @@ Q_SIGNALS:
|
|||
/** Fired when a message should be reported to the user */
|
||||
void message(const QString &title, const QString &message, unsigned int style);
|
||||
/** Encryption status of wallet changed */
|
||||
void encryptionStatusChanged(int status);
|
||||
void encryptionStatusChanged();
|
||||
/** HD-Enabled status of wallet changed (only possible during startup) */
|
||||
void hdEnabledStatusChanged(int hdEnabled);
|
||||
void hdEnabledStatusChanged();
|
||||
/** Notify that a new transaction appeared */
|
||||
void incomingTransaction(const QString& date, int unit, const CAmount& amount, const QString& type, const QString& address, const QString& label);
|
||||
void incomingTransaction(const QString& date, int unit, const CAmount& amount, const QString& type, const QString& address, const QString& label, const QString& walletName);
|
||||
/** Notify that the out of sync warning icon has been pressed */
|
||||
void outOfSyncWarningClicked();
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue