aboutsummaryrefslogtreecommitdiff
path: root/src/qt
diff options
context:
space:
mode:
Diffstat (limited to 'src/qt')
-rw-r--r--src/qt/addressbookpage.cpp68
-rw-r--r--src/qt/addressbookpage.h4
-rw-r--r--src/qt/addresstablemodel.cpp5
-rw-r--r--src/qt/addresstablemodel.h4
-rw-r--r--src/qt/bitcoin.cpp32
-rw-r--r--src/qt/bitcoinaddressvalidator.cpp2
-rw-r--r--src/qt/bitcoingui.cpp63
-rw-r--r--src/qt/bitcoingui.h18
-rw-r--r--src/qt/clientmodel.cpp10
-rw-r--r--src/qt/clientmodel.h10
-rw-r--r--src/qt/coincontroldialog.cpp5
-rw-r--r--src/qt/editaddressdialog.cpp10
-rw-r--r--src/qt/editaddressdialog.h1
-rw-r--r--src/qt/forms/addressbookpage.ui7
-rw-r--r--src/qt/forms/debugwindow.ui16
-rw-r--r--src/qt/forms/modaloverlay.ui6
-rw-r--r--src/qt/forms/sendcoinsdialog.ui4
-rw-r--r--src/qt/guiutil.cpp22
-rw-r--r--src/qt/guiutil.h5
-rw-r--r--src/qt/modaloverlay.cpp2
-rw-r--r--src/qt/paymentrequestplus.cpp1
-rw-r--r--src/qt/paymentrequestplus.h3
-rw-r--r--src/qt/paymentserver.cpp18
-rw-r--r--src/qt/receivecoinsdialog.cpp12
-rw-r--r--src/qt/receiverequestdialog.cpp9
-rw-r--r--src/qt/receiverequestdialog.h6
-rw-r--r--src/qt/rpcconsole.cpp58
-rw-r--r--src/qt/rpcconsole.h11
-rw-r--r--src/qt/sendcoinsdialog.cpp14
-rw-r--r--src/qt/sendcoinsdialog.h3
-rw-r--r--src/qt/signverifymessagedialog.cpp2
-rw-r--r--src/qt/splashscreen.cpp2
-rw-r--r--src/qt/test/paymentservertests.cpp1
-rw-r--r--src/qt/test/uritests.cpp2
-rw-r--r--src/qt/test/wallettests.cpp13
-rw-r--r--src/qt/transactiondesc.cpp6
-rw-r--r--src/qt/transactiondescdialog.cpp2
-rw-r--r--src/qt/transactionfilterproxy.cpp28
-rw-r--r--src/qt/transactionrecord.cpp9
-rw-r--r--src/qt/transactionrecord.h2
-rw-r--r--src/qt/transactiontablemodel.cpp4
-rw-r--r--src/qt/transactiontablemodel.h2
-rw-r--r--src/qt/transactionview.cpp33
-rw-r--r--src/qt/transactionview.h4
-rw-r--r--src/qt/utilitydialog.cpp2
-rw-r--r--src/qt/walletframe.cpp11
-rw-r--r--src/qt/walletframe.h3
-rw-r--r--src/qt/walletmodel.cpp38
-rw-r--r--src/qt/walletmodel.h14
-rw-r--r--src/qt/walletmodeltransaction.cpp14
-rw-r--r--src/qt/walletmodeltransaction.h5
-rw-r--r--src/qt/walletview.cpp20
-rw-r--r--src/qt/walletview.h7
53 files changed, 429 insertions, 224 deletions
diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp
index 517aa49e2b..f2ddbf259b 100644
--- a/src/qt/addressbookpage.cpp
+++ b/src/qt/addressbookpage.cpp
@@ -21,6 +21,41 @@
#include <QMessageBox>
#include <QSortFilterProxyModel>
+class AddressBookSortFilterProxyModel final : public QSortFilterProxyModel
+{
+ const QString m_type;
+
+public:
+ AddressBookSortFilterProxyModel(const QString& type, QObject* parent)
+ : QSortFilterProxyModel(parent)
+ , m_type(type)
+ {
+ setDynamicSortFilter(true);
+ setFilterCaseSensitivity(Qt::CaseInsensitive);
+ setSortCaseSensitivity(Qt::CaseInsensitive);
+ }
+
+protected:
+ bool filterAcceptsRow(int row, const QModelIndex& parent) const
+ {
+ auto model = sourceModel();
+ auto label = model->index(row, AddressTableModel::Label, parent);
+
+ if (model->data(label, AddressTableModel::TypeRole).toString() != m_type) {
+ return false;
+ }
+
+ auto address = model->index(row, AddressTableModel::Address, parent);
+
+ if (filterRegExp().indexIn(model->data(address).toString()) < 0 &&
+ filterRegExp().indexIn(model->data(label).toString()) < 0) {
+ return false;
+ }
+
+ return true;
+ }
+};
+
AddressBookPage::AddressBookPage(const PlatformStyle *platformStyle, Mode _mode, Tabs _tab, QWidget *parent) :
QDialog(parent),
ui(new Ui::AddressBookPage),
@@ -69,10 +104,12 @@ AddressBookPage::AddressBookPage(const PlatformStyle *platformStyle, Mode _mode,
case SendingTab:
ui->labelExplanation->setText(tr("These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins."));
ui->deleteAddress->setVisible(true);
+ ui->newAddress->setVisible(true);
break;
case ReceivingTab:
ui->labelExplanation->setText(tr("These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction."));
ui->deleteAddress->setVisible(false);
+ ui->newAddress->setVisible(false);
break;
}
@@ -113,24 +150,12 @@ void AddressBookPage::setModel(AddressTableModel *_model)
if(!_model)
return;
- proxyModel = new QSortFilterProxyModel(this);
+ auto type = tab == ReceivingTab ? AddressTableModel::Receive : AddressTableModel::Send;
+ proxyModel = new AddressBookSortFilterProxyModel(type, this);
proxyModel->setSourceModel(_model);
- proxyModel->setDynamicSortFilter(true);
- proxyModel->setSortCaseSensitivity(Qt::CaseInsensitive);
- proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
- switch(tab)
- {
- case ReceivingTab:
- // Receive filter
- proxyModel->setFilterRole(AddressTableModel::TypeRole);
- proxyModel->setFilterFixedString(AddressTableModel::Receive);
- break;
- case SendingTab:
- // Send filter
- proxyModel->setFilterRole(AddressTableModel::TypeRole);
- proxyModel->setFilterFixedString(AddressTableModel::Send);
- break;
- }
+
+ connect(ui->searchLineEdit, SIGNAL(textChanged(QString)), proxyModel, SLOT(setFilterWildcard(QString)));
+
ui->tableView->setModel(proxyModel);
ui->tableView->sortByColumn(0, Qt::AscendingOrder);
@@ -188,10 +213,11 @@ void AddressBookPage::on_newAddress_clicked()
if(!model)
return;
- EditAddressDialog dlg(
- tab == SendingTab ?
- EditAddressDialog::NewSendingAddress :
- EditAddressDialog::NewReceivingAddress, this);
+ if (tab == ReceivingTab) {
+ return;
+ }
+
+ EditAddressDialog dlg(EditAddressDialog::NewSendingAddress, this);
dlg.setModel(model);
if(dlg.exec())
{
diff --git a/src/qt/addressbookpage.h b/src/qt/addressbookpage.h
index 54a43478d1..8877d07330 100644
--- a/src/qt/addressbookpage.h
+++ b/src/qt/addressbookpage.h
@@ -7,6 +7,7 @@
#include <QDialog>
+class AddressBookSortFilterProxyModel;
class AddressTableModel;
class PlatformStyle;
@@ -18,7 +19,6 @@ QT_BEGIN_NAMESPACE
class QItemSelection;
class QMenu;
class QModelIndex;
-class QSortFilterProxyModel;
QT_END_NAMESPACE
/** Widget that shows a list of sending or receiving addresses.
@@ -53,7 +53,7 @@ private:
Mode mode;
Tabs tab;
QString returnValue;
- QSortFilterProxyModel *proxyModel;
+ AddressBookSortFilterProxyModel *proxyModel;
QMenu *contextMenu;
QAction *deleteAction; // to be able to explicitly disable it
QString newAddressToSelect;
diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp
index ffb5bff4de..801334483a 100644
--- a/src/qt/addresstablemodel.cpp
+++ b/src/qt/addresstablemodel.cpp
@@ -7,10 +7,9 @@
#include <qt/guiutil.h>
#include <qt/walletmodel.h>
-#include <base58.h>
+#include <key_io.h>
#include <wallet/wallet.h>
-
#include <QFont>
#include <QDebug>
@@ -442,6 +441,8 @@ int AddressTableModel::lookupAddress(const QString &address) const
}
}
+OutputType AddressTableModel::GetDefaultAddressType() const { return wallet->m_default_address_type; };
+
void AddressTableModel::emitDataChanged(int idx)
{
Q_EMIT dataChanged(index(idx, 0, QModelIndex()), index(idx, columns.length()-1, QModelIndex()));
diff --git a/src/qt/addresstablemodel.h b/src/qt/addresstablemodel.h
index 11439e25d5..ed7a4e6f43 100644
--- a/src/qt/addresstablemodel.h
+++ b/src/qt/addresstablemodel.h
@@ -8,7 +8,7 @@
#include <QAbstractTableModel>
#include <QStringList>
-enum OutputType : int;
+enum class OutputType;
class AddressTablePriv;
class WalletModel;
@@ -76,6 +76,8 @@ public:
EditStatus getEditStatus() const { return editStatus; }
+ OutputType GetDefaultAddressType() const;
+
private:
WalletModel *walletModel;
CWallet *wallet;
diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp
index cb2e6aac95..f853c04617 100644
--- a/src/qt/bitcoin.cpp
+++ b/src/qt/bitcoin.cpp
@@ -29,6 +29,7 @@
#include <init.h>
#include <rpc/server.h>
#include <ui_interface.h>
+#include <uint256.h>
#include <util.h>
#include <warnings.h>
@@ -82,6 +83,7 @@ Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin);
// Declare meta types used for QMetaObject::invokeMethod
Q_DECLARE_METATYPE(bool*)
Q_DECLARE_METATYPE(CAmount)
+Q_DECLARE_METATYPE(uint256)
static void InitMessage(const std::string &message)
{
@@ -251,7 +253,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 +335,7 @@ BitcoinApplication::BitcoinApplication(int &argc, char **argv):
pollShutdownTimer(0),
#ifdef ENABLE_WALLET
paymentServer(0),
- walletModel(0),
+ m_wallet_models(),
#endif
returnValue(0)
{
@@ -451,8 +453,10 @@ void BitcoinApplication::requestShutdown()
#ifdef ENABLE_WALLET
window->removeAllWallets();
- delete walletModel;
- walletModel = 0;
+ for (WalletModel *walletModel : m_wallet_models) {
+ delete walletModel;
+ }
+ m_wallet_models.clear();
#endif
delete clientModel;
clientModel = 0;
@@ -481,16 +485,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
@@ -617,7 +625,7 @@ int main(int argc, char *argv[])
if (!Intro::pickDataDirectory())
return EXIT_SUCCESS;
- /// 6. Determine availability of data directory and parse bitcoin.conf
+ /// 6. Determine availability of data and blocks directory and parse bitcoin.conf
/// - Do not call GetDataDir(true) before this step finishes
if (!fs::is_directory(GetDataDir(false)))
{
@@ -695,7 +703,7 @@ int main(int argc, char *argv[])
// Allow parameter interaction before we create the options model
app.parameterSetup();
// Load GUI settings from QSettings
- app.createOptionsModel(gArgs.IsArgSet("-resetguisettings"));
+ app.createOptionsModel(gArgs.GetBoolArg("-resetguisettings", false));
// Subscribe to global signals from core
uiInterface.InitMessage.connect(InitMessage);
diff --git a/src/qt/bitcoinaddressvalidator.cpp b/src/qt/bitcoinaddressvalidator.cpp
index 395ab447d2..6a76358a78 100644
--- a/src/qt/bitcoinaddressvalidator.cpp
+++ b/src/qt/bitcoinaddressvalidator.cpp
@@ -4,7 +4,7 @@
#include <qt/bitcoinaddressvalidator.h>
-#include <base58.h>
+#include <key_io.h>
/* Base58 characters are:
"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
index 4e868b7c17..e4207fce99 100644
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -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)
@@ -780,7 +799,7 @@ void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, double nVer
// Acquire current block source
enum BlockSource blockSource = clientModel->getBlockSource();
switch (blockSource) {
- case BLOCK_SOURCE_NETWORK:
+ case BlockSource::NETWORK:
if (header) {
updateHeadersSyncProgressLabel();
return;
@@ -788,17 +807,17 @@ void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, double nVer
progressBarLabel->setText(tr("Synchronizing with network..."));
updateHeadersSyncProgressLabel();
break;
- case BLOCK_SOURCE_DISK:
+ case BlockSource::DISK:
if (header) {
progressBarLabel->setText(tr("Indexing blocks on disk..."));
} else {
progressBarLabel->setText(tr("Processing blocks on disk..."));
}
break;
- case BLOCK_SOURCE_REINDEX:
+ case BlockSource::REINDEX:
progressBarLabel->setText(tr("Reindexing blocks on disk..."));
break;
- case BLOCK_SOURCE_NONE:
+ case BlockSource::NONE:
if (header) {
return;
}
@@ -923,6 +942,7 @@ void BitcoinGUI::message(const QString &title, const QString &message, unsigned
showNormalIfMinimized();
QMessageBox mBox(static_cast<QMessageBox::Icon>(nMBoxIcon), strTitle, message, buttons, this);
+ mBox.setTextFormat(Qt::PlainText);
int r = mBox.exec();
if (ret != nullptr)
*ret = r == QMessageBox::Ok;
@@ -982,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())
@@ -1078,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)
diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h
index ddb7ecb76a..b9e92f2d5b 100644
--- a/src/qt/bitcoingui.h
+++ b/src/qt/bitcoingui.h
@@ -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:
diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp
index 3642e5d4d4..40661d9ec3 100644
--- a/src/qt/clientmodel.cpp
+++ b/src/qt/clientmodel.cpp
@@ -138,9 +138,9 @@ size_t ClientModel::getMempoolDynamicUsage() const
double ClientModel::getVerificationProgress(const CBlockIndex *tipIn) const
{
CBlockIndex *tip = const_cast<CBlockIndex *>(tipIn);
+ LOCK(cs_main);
if (!tip)
{
- LOCK(cs_main);
tip = chainActive.Tip();
}
return GuessVerificationProgress(Params().TxData(), tip);
@@ -177,13 +177,13 @@ bool ClientModel::inInitialBlockDownload() const
enum BlockSource ClientModel::getBlockSource() const
{
if (fReindex)
- return BLOCK_SOURCE_REINDEX;
+ return BlockSource::REINDEX;
else if (fImporting)
- return BLOCK_SOURCE_DISK;
+ return BlockSource::DISK;
else if (getNumConnections() > 0)
- return BLOCK_SOURCE_NETWORK;
+ return BlockSource::NETWORK;
- return BLOCK_SOURCE_NONE;
+ return BlockSource::NONE;
}
void ClientModel::setNetworkActive(bool active)
diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h
index 99ec2365a9..1118bc31b3 100644
--- a/src/qt/clientmodel.h
+++ b/src/qt/clientmodel.h
@@ -20,11 +20,11 @@ QT_BEGIN_NAMESPACE
class QTimer;
QT_END_NAMESPACE
-enum BlockSource {
- BLOCK_SOURCE_NONE,
- BLOCK_SOURCE_REINDEX,
- BLOCK_SOURCE_DISK,
- BLOCK_SOURCE_NETWORK
+enum class BlockSource {
+ NONE,
+ REINDEX,
+ DISK,
+ NETWORK
};
enum NumConnections {
diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp
index 8d2e5619e0..a45e9f85c1 100644
--- a/src/qt/coincontroldialog.cpp
+++ b/src/qt/coincontroldialog.cpp
@@ -15,6 +15,7 @@
#include <wallet/coincontrol.h>
#include <init.h>
+#include <key_io.h>
#include <policy/fees.h>
#include <policy/policy.h>
#include <validation.h> // For mempool
@@ -205,7 +206,7 @@ void CoinControlDialog::showMenu(const QPoint &point)
contextMenuItem = item;
// disable some items (like Copy Transaction ID, lock, unlock) for tree roots in context menu
- if (item->text(COLUMN_TXHASH).length() == 64) // transaction hash is 64 characters (this means its a child node, so its not a parent node in tree mode)
+ if (item->text(COLUMN_TXHASH).length() == 64) // transaction hash is 64 characters (this means it is a child node, so it is not a parent node in tree mode)
{
copyTransactionHashAction->setEnabled(true);
if (model->isLockedCoin(uint256S(item->text(COLUMN_TXHASH).toStdString()), item->text(COLUMN_VOUT_INDEX).toUInt()))
@@ -373,7 +374,7 @@ void CoinControlDialog::radioListMode(bool checked)
// checkbox clicked by user
void CoinControlDialog::viewItemChanged(QTreeWidgetItem* item, int column)
{
- if (column == COLUMN_CHECKBOX && item->text(COLUMN_TXHASH).length() == 64) // transaction hash is 64 characters (this means its a child node, so its not a parent node in tree mode)
+ if (column == COLUMN_CHECKBOX && item->text(COLUMN_TXHASH).length() == 64) // transaction hash is 64 characters (this means it is a child node, so it is not a parent node in tree mode)
{
COutPoint outpt(uint256S(item->text(COLUMN_TXHASH).toStdString()), item->text(COLUMN_VOUT_INDEX).toUInt());
diff --git a/src/qt/editaddressdialog.cpp b/src/qt/editaddressdialog.cpp
index a945fc6aa0..38411c499f 100644
--- a/src/qt/editaddressdialog.cpp
+++ b/src/qt/editaddressdialog.cpp
@@ -11,7 +11,6 @@
#include <QDataWidgetMapper>
#include <QMessageBox>
-extern OutputType g_address_type;
EditAddressDialog::EditAddressDialog(Mode _mode, QWidget *parent) :
QDialog(parent),
@@ -26,10 +25,6 @@ EditAddressDialog::EditAddressDialog(Mode _mode, QWidget *parent) :
switch(mode)
{
- case NewReceivingAddress:
- setWindowTitle(tr("New receiving address"));
- ui->addressEdit->setEnabled(false);
- break;
case NewSendingAddress:
setWindowTitle(tr("New sending address"));
break;
@@ -74,13 +69,12 @@ bool EditAddressDialog::saveCurrentRow()
switch(mode)
{
- case NewReceivingAddress:
case NewSendingAddress:
address = model->addRow(
- mode == NewSendingAddress ? AddressTableModel::Send : AddressTableModel::Receive,
+ AddressTableModel::Send,
ui->labelEdit->text(),
ui->addressEdit->text(),
- g_address_type);
+ model->GetDefaultAddressType());
break;
case EditReceivingAddress:
case EditSendingAddress:
diff --git a/src/qt/editaddressdialog.h b/src/qt/editaddressdialog.h
index ddb67ece72..41c5d1708a 100644
--- a/src/qt/editaddressdialog.h
+++ b/src/qt/editaddressdialog.h
@@ -25,7 +25,6 @@ class EditAddressDialog : public QDialog
public:
enum Mode {
- NewReceivingAddress,
NewSendingAddress,
EditReceivingAddress,
EditSendingAddress
diff --git a/src/qt/forms/addressbookpage.ui b/src/qt/forms/addressbookpage.ui
index 264edeb720..7ac216286c 100644
--- a/src/qt/forms/addressbookpage.ui
+++ b/src/qt/forms/addressbookpage.ui
@@ -22,6 +22,13 @@
</widget>
</item>
<item>
+ <widget class="QLineEdit" name="searchLineEdit">
+ <property name="placeholderText">
+ <string>Enter address or label to search</string>
+ </property>
+ </widget>
+ </item>
+ <item>
<widget class="QTableView" name="tableView">
<property name="contextMenuPolicy">
<enum>Qt::CustomContextMenu</enum>
diff --git a/src/qt/forms/debugwindow.ui b/src/qt/forms/debugwindow.ui
index bba822882e..695ed61228 100644
--- a/src/qt/forms/debugwindow.ui
+++ b/src/qt/forms/debugwindow.ui
@@ -413,6 +413,22 @@
<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">
<enum>Qt::Horizontal</enum>
diff --git a/src/qt/forms/modaloverlay.ui b/src/qt/forms/modaloverlay.ui
index fdc52dc455..b5a69c578d 100644
--- a/src/qt/forms/modaloverlay.ui
+++ b/src/qt/forms/modaloverlay.ui
@@ -351,6 +351,12 @@ QLabel { color: rgb(40,40,40); }</string>
<property name="text">
<string>Hide</string>
</property>
+ <property name="focusPolicy">
+ <enum>Qt::StrongFocus</enum>
+ </property>
+ <property name="default">
+ <bool>true</bool>
+ </property>
</widget>
</item>
</layout>
diff --git a/src/qt/forms/sendcoinsdialog.ui b/src/qt/forms/sendcoinsdialog.ui
index 195a5560f7..6b31ddea90 100644
--- a/src/qt/forms/sendcoinsdialog.ui
+++ b/src/qt/forms/sendcoinsdialog.ui
@@ -848,7 +848,9 @@
<item>
<widget class="QLabel" name="labelCustomPerKilobyte">
<property name="toolTip">
- <string>If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then &quot;per kilobyte&quot; only pays 250 satoshis in fee, while &quot;total at least&quot; pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</string>
+ <string>Specify a custom fee per kB (1,000 bytes) of the transaction's virtual size.
+
+Note: Since the fee is calculated on a per-byte basis, a fee of "100 satoshis per kB" for a transaction size of 500 bytes (half of 1 kB) would ultimately yield a fee of only 50 satoshis.</string>
</property>
<property name="text">
<string>per kilobyte</string>
diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp
index edf1c29ea1..7b653a99da 100644
--- a/src/qt/guiutil.cpp
+++ b/src/qt/guiutil.cpp
@@ -9,7 +9,10 @@
#include <qt/qvalidatedlineedit.h>
#include <qt/walletmodel.h>
+#include <base58.h>
+#include <chainparams.h>
#include <primitives/transaction.h>
+#include <key_io.h>
#include <init.h>
#include <policy/policy.h>
#include <protocol.h>
@@ -134,15 +137,6 @@ void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent)
widget->setCheckValidator(new BitcoinAddressCheckValidator(parent));
}
-void setupAmountWidget(QLineEdit *widget, QWidget *parent)
-{
- QDoubleValidator *amountValidator = new QDoubleValidator(parent);
- amountValidator->setDecimals(8);
- amountValidator->setBottom(0.0);
- widget->setValidator(amountValidator);
- widget->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
-}
-
bool parseBitcoinURI(const QUrl &uri, SendCoinsRecipient *out)
{
// return if URI is not valid or is no bitcoin: URI
@@ -206,14 +200,6 @@ bool parseBitcoinURI(const QUrl &uri, SendCoinsRecipient *out)
bool parseBitcoinURI(QString uri, SendCoinsRecipient *out)
{
- // Convert bitcoin:// to bitcoin:
- //
- // Cannot handle this later, because bitcoin:// will cause Qt to see the part after // as host,
- // which will lower-case it (and thus invalidate the address).
- if(uri.startsWith("bitcoin://", Qt::CaseInsensitive))
- {
- uri.replace(0, 10, "bitcoin:");
- }
QUrl uriInstance(uri);
return parseBitcoinURI(uriInstance, out);
}
@@ -417,7 +403,7 @@ void openDebugLogfile()
bool openBitcoinConf()
{
- boost::filesystem::path pathConfig = GetConfigFile(BITCOIN_CONF_FILENAME);
+ boost::filesystem::path pathConfig = GetConfigFile(gArgs.GetArg("-conf", BITCOIN_CONF_FILENAME));
/* Create the file */
boost::filesystem::ofstream configFile(pathConfig, std::ios_base::app);
diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h
index 71a69483f5..bbbeaf2c43 100644
--- a/src/qt/guiutil.h
+++ b/src/qt/guiutil.h
@@ -40,9 +40,8 @@ namespace GUIUtil
// Return a monospace font
QFont fixedPitchFont();
- // Set up widgets for address and amounts
+ // Set up widget for address
void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent);
- void setupAmountWidget(QLineEdit *widget, QWidget *parent);
// Parse "bitcoin:" URI into recipient object, return true on successful parsing
bool parseBitcoinURI(const QUrl &uri, SendCoinsRecipient *out);
@@ -141,7 +140,7 @@ namespace GUIUtil
* Makes a QTableView last column feel as if it was being resized from its left border.
* Also makes sure the column widths are never larger than the table's viewport.
* In Qt, all columns are resizable from the right, but it's not intuitive resizing the last column from the right.
- * Usually our second to last columns behave as if stretched, and when on strech mode, columns aren't resizable
+ * Usually our second to last columns behave as if stretched, and when on stretch mode, columns aren't resizable
* interactively or programmatically.
*
* This helper object takes care of this issue.
diff --git a/src/qt/modaloverlay.cpp b/src/qt/modaloverlay.cpp
index b573dbe226..249418213f 100644
--- a/src/qt/modaloverlay.cpp
+++ b/src/qt/modaloverlay.cpp
@@ -81,7 +81,7 @@ void ModalOverlay::tipUpdate(int count, const QDateTime& blockDate, double nVeri
// keep a vector of samples of verification progress at height
blockProcessTime.push_front(qMakePair(currentDate.toMSecsSinceEpoch(), nVerificationProgress));
- // show progress speed if we have more then one sample
+ // show progress speed if we have more than one sample
if (blockProcessTime.size() >= 2) {
double progressDelta = 0;
double progressPerHour = 0;
diff --git a/src/qt/paymentrequestplus.cpp b/src/qt/paymentrequestplus.cpp
index b0ef475b35..357e98a53c 100644
--- a/src/qt/paymentrequestplus.cpp
+++ b/src/qt/paymentrequestplus.cpp
@@ -9,6 +9,7 @@
#include <qt/paymentrequestplus.h>
+#include <script/script.h>
#include <util.h>
#include <stdexcept>
diff --git a/src/qt/paymentrequestplus.h b/src/qt/paymentrequestplus.h
index be3923304f..b1b60cf582 100644
--- a/src/qt/paymentrequestplus.h
+++ b/src/qt/paymentrequestplus.h
@@ -10,7 +10,8 @@
#include <qt/paymentrequest.pb.h>
#pragma GCC diagnostic pop
-#include <base58.h>
+#include <amount.h>
+#include <script/script.h>
#include <openssl/x509.h>
diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp
index bc69d4f945..65ef250440 100644
--- a/src/qt/paymentserver.cpp
+++ b/src/qt/paymentserver.cpp
@@ -8,9 +8,9 @@
#include <qt/guiutil.h>
#include <qt/optionsmodel.h>
-#include <base58.h>
#include <chainparams.h>
#include <policy/policy.h>
+#include <key_io.h>
#include <ui_interface.h>
#include <util.h>
#include <wallet/wallet.h>
@@ -404,7 +404,12 @@ void PaymentServer::handleURIOrFile(const QString& s)
return;
}
- if (s.startsWith(BITCOIN_IPC_PREFIX, Qt::CaseInsensitive)) // bitcoin: URI
+ if (s.startsWith("bitcoin://", Qt::CaseInsensitive))
+ {
+ Q_EMIT message(tr("URI handling"), tr("'bitcoin://' is not a valid URI. Use 'bitcoin:' instead."),
+ CClientUIInterface::MSG_ERROR);
+ }
+ else if (s.startsWith(BITCOIN_IPC_PREFIX, Qt::CaseInsensitive)) // bitcoin: URI
{
#if QT_VERSION < 0x050000
QUrl uri(s);
@@ -634,8 +639,6 @@ void PaymentServer::fetchPaymentACK(CWallet* wallet, const SendCoinsRecipient& r
payment.add_transactions(transaction.data(), transaction.size());
// Create a new refund address, or re-use:
- QString account = tr("Refund from %1").arg(recipient.authenticatedMerchant);
- std::string strAccount = account.toStdString();
CPubKey newKey;
if (wallet->GetKeyFromPool(newKey)) {
// BIP70 requests encode the scriptPubKey directly, so we are not restricted to address
@@ -643,10 +646,11 @@ void PaymentServer::fetchPaymentACK(CWallet* wallet, const SendCoinsRecipient& r
// use for change. Despite an actual payment and not change, this is a close match:
// it's the output type we use subject to privacy issues, but not restricted by what
// other software supports.
- const OutputType change_type = g_change_type != OUTPUT_TYPE_NONE ? g_change_type : g_address_type;
+ const OutputType change_type = wallet->m_default_change_type != OutputType::NONE ? wallet->m_default_change_type : wallet->m_default_address_type;
wallet->LearnRelatedScripts(newKey, change_type);
CTxDestination dest = GetDestinationForKey(newKey, change_type);
- wallet->SetAddressBook(dest, strAccount, "refund");
+ std::string label = tr("Refund from %1").arg(recipient.authenticatedMerchant).toStdString();
+ wallet->SetAddressBook(dest, label, "refund");
CScript s = GetScriptForDestination(dest);
payments::Output* refund_to = payment.add_refund_to();
@@ -770,7 +774,7 @@ bool PaymentServer::verifyExpired(const payments::PaymentDetails& requestDetails
{
bool fVerified = (requestDetails.has_expires() && (int64_t)requestDetails.expires() < GetTime());
if (fVerified) {
- const QString requestExpires = QString::fromStdString(DateTimeStrFormat("%Y-%m-%d %H:%M:%S", (int64_t)requestDetails.expires()));
+ const QString requestExpires = QString::fromStdString(FormatISO8601DateTime((int64_t)requestDetails.expires()));
qWarning() << QString("PaymentServer::%1: Payment request expired \"%2\".")
.arg(__func__)
.arg(requestExpires);
diff --git a/src/qt/receivecoinsdialog.cpp b/src/qt/receivecoinsdialog.cpp
index 7fd5285467..c8b6366db0 100644
--- a/src/qt/receivecoinsdialog.cpp
+++ b/src/qt/receivecoinsdialog.cpp
@@ -95,13 +95,13 @@ void ReceiveCoinsDialog::setModel(WalletModel *_model)
columnResizingFixer = new GUIUtil::TableViewLastColumnResizingFixer(tableView, AMOUNT_MINIMUM_COLUMN_WIDTH, DATE_COLUMN_WIDTH, this);
// configure bech32 checkbox, disable if launched with legacy as default:
- if (model->getDefaultAddressType() == OUTPUT_TYPE_BECH32) {
+ if (model->getDefaultAddressType() == OutputType::BECH32) {
ui->useBech32->setCheckState(Qt::Checked);
} else {
ui->useBech32->setCheckState(Qt::Unchecked);
}
- ui->useBech32->setVisible(model->getDefaultAddressType() != OUTPUT_TYPE_LEGACY);
+ ui->useBech32->setVisible(model->getDefaultAddressType() != OutputType::LEGACY);
}
}
@@ -145,15 +145,15 @@ void ReceiveCoinsDialog::on_receiveButton_clicked()
QString label = ui->reqLabel->text();
/* Generate new receiving address */
OutputType address_type = model->getDefaultAddressType();
- if (address_type != OUTPUT_TYPE_LEGACY) {
- address_type = ui->useBech32->isChecked() ? OUTPUT_TYPE_BECH32 : OUTPUT_TYPE_P2SH_SEGWIT;
+ if (address_type != OutputType::LEGACY) {
+ address_type = ui->useBech32->isChecked() ? OutputType::BECH32 : OutputType::P2SH_SEGWIT;
}
address = model->getAddressTableModel()->addRow(AddressTableModel::Receive, label, "", address_type);
SendCoinsRecipient info(address, label,
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();
diff --git a/src/qt/receiverequestdialog.cpp b/src/qt/receiverequestdialog.cpp
index d4cb0e5ba2..75146e2214 100644
--- a/src/qt/receiverequestdialog.cpp
+++ b/src/qt/receiverequestdialog.cpp
@@ -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
diff --git a/src/qt/receiverequestdialog.h b/src/qt/receiverequestdialog.h
index 21bbf1edb7..23c5529535 100644
--- a/src/qt/receiverequestdialog.h
+++ b/src/qt/receiverequestdialog.h
@@ -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;
};
diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp
index 1aa4de03ca..c41e19f6f5 100644
--- a/src/qt/rpcconsole.cpp
+++ b/src/qt/rpcconsole.cpp
@@ -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
diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h
index c41cbb0933..c97260b2c3 100644
--- a/src/qt/rpcconsole.h
+++ b/src/qt/rpcconsole.h
@@ -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();
diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp
index 871822ccb4..8a52aadbb0 100644
--- a/src/qt/sendcoinsdialog.cpp
+++ b/src/qt/sendcoinsdialog.cpp
@@ -14,8 +14,8 @@
#include <qt/platformstyle.h>
#include <qt/sendcoinsentry.h>
-#include <base58.h>
#include <chainparams.h>
+#include <key_io.h>
#include <wallet/coincontrol.h>
#include <validation.h> // mempool and minRelayTxFee
#include <ui_interface.h>
@@ -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;
@@ -369,12 +372,19 @@ void SendCoinsDialog::on_sendButton_clicked()
accept();
CoinControlDialog::coinControl()->UnSelectAll();
coinControlUpdateLabels();
+ Q_EMIT coinsSent(currentTransaction.getTransaction()->GetHash());
}
fNewRecipientAllowed = true;
}
void SendCoinsDialog::clear()
{
+ // Clear coin control settings
+ CoinControlDialog::coinControl()->UnSelectAll();
+ ui->checkBoxCoinControlChange->setChecked(false);
+ ui->lineEditCoinControlChange->clear();
+ coinControlUpdateLabels();
+
// Remove entries until only one left
while(ui->entries->count())
{
diff --git a/src/qt/sendcoinsdialog.h b/src/qt/sendcoinsdialog.h
index 7c27785d12..48885bbcad 100644
--- a/src/qt/sendcoinsdialog.h
+++ b/src/qt/sendcoinsdialog.h
@@ -54,6 +54,9 @@ public Q_SLOTS:
void setBalance(const CAmount& balance, const CAmount& unconfirmedBalance, const CAmount& immatureBalance,
const CAmount& watchOnlyBalance, const CAmount& watchUnconfBalance, const CAmount& watchImmatureBalance);
+Q_SIGNALS:
+ void coinsSent(const uint256& txid);
+
private:
Ui::SendCoinsDialog *ui;
ClientModel *clientModel;
diff --git a/src/qt/signverifymessagedialog.cpp b/src/qt/signverifymessagedialog.cpp
index 364dcd6f45..8dade8df79 100644
--- a/src/qt/signverifymessagedialog.cpp
+++ b/src/qt/signverifymessagedialog.cpp
@@ -10,8 +10,8 @@
#include <qt/platformstyle.h>
#include <qt/walletmodel.h>
-#include <base58.h>
#include <init.h>
+#include <key_io.h>
#include <validation.h> // For strMessageMagic
#include <wallet/wallet.h>
diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp
index 5df1282f73..66e9dd0465 100644
--- a/src/qt/splashscreen.cpp
+++ b/src/qt/splashscreen.cpp
@@ -91,7 +91,7 @@ SplashScreen::SplashScreen(Qt::WindowFlags f, const NetworkStyle *networkStyle)
pixPaint.setFont(QFont(font, 15*fontFactor));
- // if the version string is to long, reduce size
+ // if the version string is too long, reduce size
fm = pixPaint.fontMetrics();
int versionTextWidth = fm.width(versionText);
if(versionTextWidth > titleTextWidth+paddingRight-10) {
diff --git a/src/qt/test/paymentservertests.cpp b/src/qt/test/paymentservertests.cpp
index 6e80625123..29ef4b4c9e 100644
--- a/src/qt/test/paymentservertests.cpp
+++ b/src/qt/test/paymentservertests.cpp
@@ -8,6 +8,7 @@
#include <qt/test/paymentrequestdata.h>
#include <amount.h>
+#include <chainparams.h>
#include <random.h>
#include <script/script.h>
#include <script/standard.h>
diff --git a/src/qt/test/uritests.cpp b/src/qt/test/uritests.cpp
index 8415250630..59938f704a 100644
--- a/src/qt/test/uritests.cpp
+++ b/src/qt/test/uritests.cpp
@@ -51,7 +51,7 @@ void URITests::uriTests()
QVERIFY(rv.address == QString("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W"));
QVERIFY(rv.label == QString());
- QVERIFY(GUIUtil::parseBitcoinURI("bitcoin://175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?message=Wikipedia Example Address", &rv));
+ QVERIFY(GUIUtil::parseBitcoinURI("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?message=Wikipedia Example Address", &rv));
QVERIFY(rv.address == QString("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W"));
QVERIFY(rv.label == QString());
diff --git a/src/qt/test/wallettests.cpp b/src/qt/test/wallettests.cpp
index cd49292138..c9898e52ca 100644
--- a/src/qt/test/wallettests.cpp
+++ b/src/qt/test/wallettests.cpp
@@ -10,6 +10,7 @@
#include <qt/transactiontablemodel.h>
#include <qt/transactionview.h>
#include <qt/walletmodel.h>
+#include <key_io.h>
#include <test/test_bitcoin.h>
#include <validation.h>
#include <wallet/wallet.h>
@@ -149,22 +150,17 @@ void BumpFee(TransactionView& view, const uint256& txid, bool expectDisabled, st
// src/qt/test/test_bitcoin-qt -platform cocoa # macOS
void TestGUI()
{
- g_address_type = OUTPUT_TYPE_P2SH_SEGWIT;
- g_change_type = OUTPUT_TYPE_P2SH_SEGWIT;
-
// Set up wallet and chain with 105 blocks (5 mature blocks for spending).
TestChain100Setup test;
for (int i = 0; i < 5; ++i) {
test.CreateAndProcessBlock({}, GetScriptForRawPubKey(test.coinbaseKey.GetPubKey()));
}
- bitdb.MakeMock();
- std::unique_ptr<CWalletDBWrapper> dbw(new CWalletDBWrapper(&bitdb, "wallet_test.dat"));
- CWallet wallet(std::move(dbw));
+ CWallet wallet("mock", CWalletDBWrapper::CreateMock());
bool firstRun;
wallet.LoadWallet(firstRun);
{
LOCK(wallet.cs_wallet);
- wallet.SetAddressBook(GetDestinationForKey(test.coinbaseKey.GetPubKey(), g_address_type), "", "receive");
+ wallet.SetAddressBook(GetDestinationForKey(test.coinbaseKey.GetPubKey(), wallet.m_default_address_type), "", "receive");
wallet.AddKeyPubKey(test.coinbaseKey, test.coinbaseKey.GetPubKey());
}
{
@@ -260,9 +256,6 @@ void TestGUI()
QPushButton* removeRequestButton = receiveCoinsDialog.findChild<QPushButton*>("removeRequestButton");
removeRequestButton->click();
QCOMPARE(requestTableModel->rowCount({}), currentRowCount-1);
-
- bitdb.Flush(true);
- bitdb.Reset();
}
}
diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp
index c1d28be0ab..ec5a66bc9f 100644
--- a/src/qt/transactiondesc.cpp
+++ b/src/qt/transactiondesc.cpp
@@ -9,14 +9,15 @@
#include <qt/paymentserver.h>
#include <qt/transactionrecord.h>
-#include <base58.h>
#include <consensus/consensus.h>
+#include <key_io.h>
#include <validation.h>
#include <script/script.h>
#include <timedata.h>
#include <util.h>
#include <wallet/db.h>
#include <wallet/wallet.h>
+#include <policy/policy.h>
#include <stdint.h>
#include <string>
@@ -239,8 +240,9 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, TransactionReco
if (wtx.mapValue.count("comment") && !wtx.mapValue["comment"].empty())
strHTML += "<br><b>" + tr("Comment") + ":</b><br>" + GUIUtil::HtmlEscape(wtx.mapValue["comment"], true) + "<br>";
- strHTML += "<b>" + tr("Transaction ID") + ":</b> " + rec->getTxID() + "<br>";
+ strHTML += "<b>" + tr("Transaction ID") + ":</b> " + rec->getTxHash() + "<br>";
strHTML += "<b>" + tr("Transaction total size") + ":</b> " + QString::number(wtx.tx->GetTotalSize()) + " bytes<br>";
+ strHTML += "<b>" + tr("Transaction virtual size") + ":</b> " + QString::number(GetVirtualTransactionSize(*wtx.tx)) + " bytes<br>";
strHTML += "<b>" + tr("Output index") + ":</b> " + QString::number(rec->getOutputIndex()) + "<br>";
// Message from normal bitcoin:URI (bitcoin:123...?message=example)
diff --git a/src/qt/transactiondescdialog.cpp b/src/qt/transactiondescdialog.cpp
index 161fccd462..7bf4d3351c 100644
--- a/src/qt/transactiondescdialog.cpp
+++ b/src/qt/transactiondescdialog.cpp
@@ -14,7 +14,7 @@ TransactionDescDialog::TransactionDescDialog(const QModelIndex &idx, QWidget *pa
ui(new Ui::TransactionDescDialog)
{
ui->setupUi(this);
- setWindowTitle(tr("Details for %1").arg(idx.data(TransactionTableModel::TxIDRole).toString()));
+ setWindowTitle(tr("Details for %1").arg(idx.data(TransactionTableModel::TxHashRole).toString()));
QString desc = idx.data(TransactionTableModel::LongDescriptionRole).toString();
ui->detailText->setHtml(desc);
}
diff --git a/src/qt/transactionfilterproxy.cpp b/src/qt/transactionfilterproxy.cpp
index 39d03fa547..6301af7553 100644
--- a/src/qt/transactionfilterproxy.cpp
+++ b/src/qt/transactionfilterproxy.cpp
@@ -31,31 +31,35 @@ bool TransactionFilterProxy::filterAcceptsRow(int sourceRow, const QModelIndex &
{
QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
- int type = index.data(TransactionTableModel::TypeRole).toInt();
- QDateTime datetime = index.data(TransactionTableModel::DateRole).toDateTime();
- bool involvesWatchAddress = index.data(TransactionTableModel::WatchonlyRole).toBool();
- QString address = index.data(TransactionTableModel::AddressRole).toString();
- QString label = index.data(TransactionTableModel::LabelRole).toString();
- QString txid = index.data(TransactionTableModel::TxIDRole).toString();
- qint64 amount = llabs(index.data(TransactionTableModel::AmountRole).toLongLong());
int status = index.data(TransactionTableModel::StatusRole).toInt();
-
- if(!showInactive && status == TransactionStatus::Conflicted)
+ if (!showInactive && status == TransactionStatus::Conflicted)
return false;
- if(!(TYPE(type) & typeFilter))
+
+ int type = index.data(TransactionTableModel::TypeRole).toInt();
+ if (!(TYPE(type) & typeFilter))
return false;
+
+ bool involvesWatchAddress = index.data(TransactionTableModel::WatchonlyRole).toBool();
if (involvesWatchAddress && watchOnlyFilter == WatchOnlyFilter_No)
return false;
if (!involvesWatchAddress && watchOnlyFilter == WatchOnlyFilter_Yes)
return false;
- if(datetime < dateFrom || datetime > dateTo)
+
+ QDateTime datetime = index.data(TransactionTableModel::DateRole).toDateTime();
+ if (datetime < dateFrom || datetime > dateTo)
return false;
+
+ QString address = index.data(TransactionTableModel::AddressRole).toString();
+ QString label = index.data(TransactionTableModel::LabelRole).toString();
+ QString txid = index.data(TransactionTableModel::TxHashRole).toString();
if (!address.contains(m_search_string, Qt::CaseInsensitive) &&
! label.contains(m_search_string, Qt::CaseInsensitive) &&
! txid.contains(m_search_string, Qt::CaseInsensitive)) {
return false;
}
- if(amount < minAmount)
+
+ qint64 amount = llabs(index.data(TransactionTableModel::AmountRole).toLongLong());
+ if (amount < minAmount)
return false;
return true;
diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp
index de3e885e8f..cc30cf747d 100644
--- a/src/qt/transactionrecord.cpp
+++ b/src/qt/transactionrecord.cpp
@@ -4,8 +4,8 @@
#include <qt/transactionrecord.h>
-#include <base58.h>
#include <consensus/consensus.h>
+#include <key_io.h>
#include <validation.h>
#include <timedata.h>
#include <wallet/wallet.h>
@@ -167,10 +167,7 @@ void TransactionRecord::updateStatus(const CWalletTx &wtx)
// Determine transaction status
// Find the block the tx is in
- CBlockIndex* pindex = nullptr;
- BlockMap::iterator mi = mapBlockIndex.find(wtx.hashBlock);
- if (mi != mapBlockIndex.end())
- pindex = (*mi).second;
+ const CBlockIndex* pindex = LookupBlockIndex(wtx.hashBlock);
// Sort order, unrecorded transactions sort to the top
status.sortKey = strprintf("%010d-%01d-%010u-%03d",
@@ -254,7 +251,7 @@ bool TransactionRecord::statusUpdateNeeded() const
return status.cur_num_blocks != chainActive.Height() || status.needsUpdate;
}
-QString TransactionRecord::getTxID() const
+QString TransactionRecord::getTxHash() const
{
return QString::fromStdString(hash.ToString());
}
diff --git a/src/qt/transactionrecord.h b/src/qt/transactionrecord.h
index 29a3cd8de7..5321d05d15 100644
--- a/src/qt/transactionrecord.h
+++ b/src/qt/transactionrecord.h
@@ -129,7 +129,7 @@ public:
bool involvesWatchAddress;
/** Return the unique identifier for this transaction (part) */
- QString getTxID() const;
+ QString getTxHash() const;
/** Return the output index of the subtransaction */
int getOutputIndex() const;
diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp
index 626d4c0bdc..84800125fe 100644
--- a/src/qt/transactiontablemodel.cpp
+++ b/src/qt/transactiontablemodel.cpp
@@ -615,10 +615,8 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const
return walletModel->getAddressTableModel()->labelForAddress(QString::fromStdString(rec->address));
case AmountRole:
return qint64(rec->credit + rec->debit);
- case TxIDRole:
- return rec->getTxID();
case TxHashRole:
- return QString::fromStdString(rec->hash.ToString());
+ return rec->getTxHash();
case TxHexRole:
return priv->getTxHex(rec);
case TxPlainTextRole:
diff --git a/src/qt/transactiontablemodel.h b/src/qt/transactiontablemodel.h
index 8f58962d17..781874d160 100644
--- a/src/qt/transactiontablemodel.h
+++ b/src/qt/transactiontablemodel.h
@@ -56,8 +56,6 @@ public:
LabelRole,
/** Net amount of transaction */
AmountRole,
- /** Unique identifier */
- TxIDRole,
/** Transaction hash */
TxHashRole,
/** Transaction data, hex-encoded */
diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp
index 88f8f463bc..26391452da 100644
--- a/src/qt/transactionview.cpp
+++ b/src/qt/transactionview.cpp
@@ -263,8 +263,7 @@ void TransactionView::setModel(WalletModel *_model)
void TransactionView::chooseDate(int idx)
{
- if(!transactionProxyModel)
- return;
+ if (!transactionProxyModel) return;
QDate current = QDate::currentDate();
dateRangeWidget->setVisible(false);
switch(dateWidget->itemData(idx).toInt())
@@ -372,7 +371,7 @@ void TransactionView::exportClicked()
writer.addColumn(tr("Label"), 0, TransactionTableModel::LabelRole);
writer.addColumn(tr("Address"), 0, TransactionTableModel::AddressRole);
writer.addColumn(BitcoinUnits::getAmountColumnTitle(model->getOptionsModel()->getDisplayUnit()), 0, TransactionTableModel::FormattedAmountRole);
- writer.addColumn(tr("ID"), 0, TransactionTableModel::TxIDRole);
+ writer.addColumn(tr("ID"), 0, TransactionTableModel::TxHashRole);
if(!writer.write()) {
Q_EMIT message(tr("Exporting Failed"), tr("There was an error trying to save the transaction history to %1.").arg(filename),
@@ -456,7 +455,7 @@ void TransactionView::copyAmount()
void TransactionView::copyTxID()
{
- GUIUtil::copyEntryData(transactionView, 0, TransactionTableModel::TxIDRole);
+ GUIUtil::copyEntryData(transactionView, 0, TransactionTableModel::TxHashRole);
}
void TransactionView::copyTxHex()
@@ -592,6 +591,32 @@ void TransactionView::focusTransaction(const QModelIndex &idx)
transactionView->setFocus();
}
+void TransactionView::focusTransaction(const uint256& txid)
+{
+ if (!transactionProxyModel)
+ return;
+
+ const QModelIndexList results = this->model->getTransactionTableModel()->match(
+ this->model->getTransactionTableModel()->index(0,0),
+ TransactionTableModel::TxHashRole,
+ QString::fromStdString(txid.ToString()), -1);
+
+ transactionView->setFocus();
+ transactionView->selectionModel()->clearSelection();
+ for (const QModelIndex& index : results) {
+ const QModelIndex targetIndex = transactionProxyModel->mapFromSource(index);
+ transactionView->selectionModel()->select(
+ targetIndex,
+ QItemSelectionModel::Rows | QItemSelectionModel::Select);
+ // Called once per destination to ensure all results are in view, unless
+ // transactions are not ordered by (ascending or descending) date.
+ transactionView->scrollTo(targetIndex);
+ // scrollTo() does not scroll far enough the first time when transactions
+ // are ordered by ascending date.
+ if (index == results[0]) transactionView->scrollTo(targetIndex);
+ }
+}
+
// We override the virtual resizeEvent of the QWidget to adjust tables column
// sizes as the tables width is proportional to the dialogs width.
void TransactionView::resizeEvent(QResizeEvent* event)
diff --git a/src/qt/transactionview.h b/src/qt/transactionview.h
index 82e929b53f..66dc5bc86b 100644
--- a/src/qt/transactionview.h
+++ b/src/qt/transactionview.h
@@ -7,6 +7,8 @@
#include <qt/guiutil.h>
+#include <uint256.h>
+
#include <QWidget>
#include <QKeyEvent>
@@ -116,7 +118,7 @@ public Q_SLOTS:
void changedSearch();
void exportClicked();
void focusTransaction(const QModelIndex&);
-
+ void focusTransaction(const uint256& txid);
};
#endif // BITCOIN_QT_TRANSACTIONVIEW_H
diff --git a/src/qt/utilitydialog.cpp b/src/qt/utilitydialog.cpp
index 65e7775f2b..c19e6aae78 100644
--- a/src/qt/utilitydialog.cpp
+++ b/src/qt/utilitydialog.cpp
@@ -77,7 +77,7 @@ HelpMessageDialog::HelpMessageDialog(QWidget *parent, bool about) :
cursor.insertText(header);
cursor.insertBlock();
- std::string strUsage = HelpMessage(HMM_BITCOIN_QT);
+ std::string strUsage = HelpMessage(HelpMessageMode::BITCOIN_QT);
const bool showDebug = gArgs.GetBoolArg("-help-debug", false);
strUsage += HelpMessageGroup(tr("UI Options:").toStdString());
if (showDebug) {
diff --git a/src/qt/walletframe.cpp b/src/qt/walletframe.cpp
index c0b9d04269..5b13353d7b 100644
--- a/src/qt/walletframe.cpp
+++ b/src/qt/walletframe.cpp
@@ -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);
diff --git a/src/qt/walletframe.h b/src/qt/walletframe.h
index 42ce69fea1..6eedcf370c 100644
--- a/src/qt/walletframe.h
+++ b/src/qt/walletframe.h
@@ -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:
diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp
index 34954a6bfa..795302be58 100644
--- a/src/qt/walletmodel.cpp
+++ b/src/qt/walletmodel.cpp
@@ -14,8 +14,8 @@
#include <qt/sendcoinsdialog.h>
#include <qt/transactiontablemodel.h>
-#include <base58.h>
#include <chain.h>
+#include <key_io.h>
#include <keystore.h>
#include <validation.h>
#include <net.h> // for g_connman
@@ -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()
@@ -275,9 +276,9 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact
int nChangePosRet = -1;
std::string strFailReason;
- CWalletTx *newTx = transaction.getTransaction();
+ CTransactionRef& newTx = transaction.getTransaction();
CReserveKey *keyChange = transaction.getPossibleKeyChange();
- bool fCreated = wallet->CreateTransaction(vecSend, *newTx, *keyChange, nFeeRequired, nChangePosRet, strFailReason, coinControl);
+ bool fCreated = wallet->CreateTransaction(vecSend, newTx, *keyChange, nFeeRequired, nChangePosRet, strFailReason, coinControl);
transaction.setTransactionFee(nFeeRequired);
if (fSubtractFeeFromAmount && fCreated)
transaction.reassignAmounts(nChangePosRet);
@@ -309,8 +310,8 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(WalletModelTransaction &tran
{
LOCK2(cs_main, wallet->cs_wallet);
- CWalletTx *newTx = transaction.getTransaction();
+ std::vector<std::pair<std::string, std::string>> vOrderForm;
for (const SendCoinsRecipient &rcp : transaction.getRecipients())
{
if (rcp.paymentRequest.IsInitialized())
@@ -321,22 +322,22 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(WalletModelTransaction &tran
}
// Store PaymentRequests in wtx.vOrderForm in wallet.
- std::string key("PaymentRequest");
std::string value;
rcp.paymentRequest.SerializeToString(&value);
- newTx->vOrderForm.push_back(make_pair(key, value));
+ vOrderForm.emplace_back("PaymentRequest", std::move(value));
}
else if (!rcp.message.isEmpty()) // Message from normal bitcoin:URI (bitcoin:123...?message=example)
- newTx->vOrderForm.push_back(make_pair("Message", rcp.message.toStdString()));
+ vOrderForm.emplace_back("Message", rcp.message.toStdString());
}
+ CTransactionRef& newTx = transaction.getTransaction();
CReserveKey *keyChange = transaction.getPossibleKeyChange();
CValidationState state;
- if(!wallet->CommitTransaction(*newTx, *keyChange, g_connman.get(), state))
+ if (!wallet->CommitTransaction(newTx, {} /* mapValue */, std::move(vOrderForm), {} /* fromAccount */, *keyChange, g_connman.get(), state))
return SendCoinsReturn(TransactionCommitFailed, QString::fromStdString(state.GetRejectReason()));
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
- ssTx << *newTx->tx;
+ ssTx << newTx;
transaction_array.append(&(ssTx[0]), ssTx.size());
}
@@ -698,7 +699,7 @@ bool WalletModel::bumpFee(uint256 hash)
confirmationDialog.exec();
QMessageBox::StandardButton retval = static_cast<QMessageBox::StandardButton>(confirmationDialog.result());
- // cancel sign&broadcast if users doesn't want to bump the fee
+ // cancel sign&broadcast if user doesn't want to bump the fee
if (retval != QMessageBox::Yes) {
return false;
}
@@ -736,10 +737,21 @@ bool WalletModel::hdEnabled() const
OutputType WalletModel::getDefaultAddressType() const
{
- return g_address_type;
+ return wallet->m_default_address_type;
}
int WalletModel::getDefaultConfirmTarget() const
{
return nTxConfirmTarget;
}
+
+QString WalletModel::getWalletName() const
+{
+ LOCK(wallet->cs_wallet);
+ return QString::fromStdString(wallet->GetName());
+}
+
+bool WalletModel::isMultiwallet()
+{
+ return gArgs.GetArgs("-wallet").size() > 1;
+}
diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h
index 9e13de79be..ff4b38a804 100644
--- a/src/qt/walletmodel.h
+++ b/src/qt/walletmodel.h
@@ -5,6 +5,11 @@
#ifndef BITCOIN_QT_WALLETMODEL_H
#define BITCOIN_QT_WALLETMODEL_H
+#include <amount.h>
+#include <key.h>
+#include <serialize.h>
+#include <script/standard.h>
+
#include <qt/paymentrequestplus.h>
#include <qt/walletmodeltransaction.h>
@@ -15,7 +20,7 @@
#include <QObject>
-enum OutputType : int;
+enum class OutputType;
class AddressTableModel;
class OptionsModel;
@@ -131,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;
@@ -220,6 +227,9 @@ public:
int getDefaultConfirmTarget() const;
+ QString getWalletName() const;
+
+ static bool isMultiwallet();
private:
CWallet *wallet;
bool fHaveWatchOnly;
@@ -255,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;
diff --git a/src/qt/walletmodeltransaction.cpp b/src/qt/walletmodeltransaction.cpp
index 4b2bef2690..4df8a5687e 100644
--- a/src/qt/walletmodeltransaction.cpp
+++ b/src/qt/walletmodeltransaction.cpp
@@ -12,12 +12,6 @@ WalletModelTransaction::WalletModelTransaction(const QList<SendCoinsRecipient> &
walletTransaction(0),
fee(0)
{
- walletTransaction = new CWalletTx();
-}
-
-WalletModelTransaction::~WalletModelTransaction()
-{
- delete walletTransaction;
}
QList<SendCoinsRecipient> WalletModelTransaction::getRecipients() const
@@ -25,14 +19,14 @@ QList<SendCoinsRecipient> WalletModelTransaction::getRecipients() const
return recipients;
}
-CWalletTx *WalletModelTransaction::getTransaction() const
+CTransactionRef& WalletModelTransaction::getTransaction()
{
return walletTransaction;
}
unsigned int WalletModelTransaction::getTransactionSize()
{
- return (!walletTransaction ? 0 : ::GetVirtualTransactionSize(*walletTransaction->tx));
+ return (!walletTransaction ? 0 : ::GetVirtualTransactionSize(*walletTransaction));
}
CAmount WalletModelTransaction::getTransactionFee() const
@@ -62,7 +56,7 @@ void WalletModelTransaction::reassignAmounts(int nChangePosRet)
if (out.amount() <= 0) continue;
if (i == nChangePosRet)
i++;
- subtotal += walletTransaction->tx->vout[i].nValue;
+ subtotal += walletTransaction->vout[i].nValue;
i++;
}
rcp.amount = subtotal;
@@ -71,7 +65,7 @@ void WalletModelTransaction::reassignAmounts(int nChangePosRet)
{
if (i == nChangePosRet)
i++;
- rcp.amount = walletTransaction->tx->vout[i].nValue;
+ rcp.amount = walletTransaction->vout[i].nValue;
i++;
}
}
diff --git a/src/qt/walletmodeltransaction.h b/src/qt/walletmodeltransaction.h
index cd531dba4b..931e960d18 100644
--- a/src/qt/walletmodeltransaction.h
+++ b/src/qt/walletmodeltransaction.h
@@ -20,11 +20,10 @@ class WalletModelTransaction
{
public:
explicit WalletModelTransaction(const QList<SendCoinsRecipient> &recipients);
- ~WalletModelTransaction();
QList<SendCoinsRecipient> getRecipients() const;
- CWalletTx *getTransaction() const;
+ CTransactionRef& getTransaction();
unsigned int getTransactionSize();
void setTransactionFee(const CAmount& newFee);
@@ -39,7 +38,7 @@ public:
private:
QList<SendCoinsRecipient> recipients;
- CWalletTx *walletTransaction;
+ CTransactionRef walletTransaction;
std::unique_ptr<CReserveKey> keyChange;
CAmount fee;
};
diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp
index 7eced9289d..cc4300a7a1 100644
--- a/src/qt/walletview.cpp
+++ b/src/qt/walletview.cpp
@@ -68,6 +68,9 @@ WalletView::WalletView(const PlatformStyle *_platformStyle, QWidget *parent):
connect(overviewPage, SIGNAL(transactionClicked(QModelIndex)), transactionView, SLOT(focusTransaction(QModelIndex)));
connect(overviewPage, SIGNAL(outOfSyncWarningClicked()), this, SLOT(requestedSyncWarningInfo()));
+ // Highlight transaction after send
+ connect(sendCoinsPage, SIGNAL(coinsSent(uint256)), transactionView, SLOT(focusTransaction(uint256)));
+
// Double-clicking on a transaction on the transaction history page shows details
connect(transactionView, SIGNAL(doubleClicked(QModelIndex)), transactionView, SLOT(showDetails()));
@@ -91,17 +94,20 @@ void WalletView::setBitcoinGUI(BitcoinGUI *gui)
// Clicking on a transaction on the overview page simply sends you to transaction history page
connect(overviewPage, SIGNAL(transactionClicked(QModelIndex)), gui, SLOT(gotoHistoryPage()));
+ // Navigate to transaction history page after send
+ connect(sendCoinsPage, SIGNAL(coinsSent(uint256)), gui, SLOT(gotoHistoryPage()));
+
// Receive and report messages
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()));
}
}
@@ -131,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)),
@@ -166,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()
@@ -228,7 +234,7 @@ void WalletView::showOutOfSyncWarning(bool fShow)
void WalletView::updateEncryptionStatus()
{
- Q_EMIT encryptionStatusChanged(walletModel->getEncryptionStatus());
+ Q_EMIT encryptionStatusChanged();
}
void WalletView::encryptWallet(bool status)
diff --git a/src/qt/walletview.h b/src/qt/walletview.h
index 30d68e4eff..878a5966d6 100644
--- a/src/qt/walletview.h
+++ b/src/qt/walletview.h
@@ -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();
};