64cc3ecbd1
Introduce a PlatformStyle to handle platform-specific customization of the UI. This replaces 'scicon', as well as #ifdefs to determine whether to place icons on buttons. The selected PlatformStyle defaults to the platform that the application was compiled on, but can be overridden from the command line with `-uiplatform=<x>`. Also fixes the warning from #6328.
325 lines
10 KiB
C++
325 lines
10 KiB
C++
// Copyright (c) 2011-2013 The Bitcoin Core developers
|
|
// Distributed under the MIT software license, see the accompanying
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
#include "walletview.h"
|
|
|
|
#include "addressbookpage.h"
|
|
#include "askpassphrasedialog.h"
|
|
#include "bitcoingui.h"
|
|
#include "clientmodel.h"
|
|
#include "guiutil.h"
|
|
#include "optionsmodel.h"
|
|
#include "overviewpage.h"
|
|
#include "platformstyle.h"
|
|
#include "receivecoinsdialog.h"
|
|
#include "sendcoinsdialog.h"
|
|
#include "signverifymessagedialog.h"
|
|
#include "transactiontablemodel.h"
|
|
#include "transactionview.h"
|
|
#include "walletmodel.h"
|
|
#include "utilitydialog.h"
|
|
|
|
#include "ui_interface.h"
|
|
|
|
#include <QAction>
|
|
#include <QActionGroup>
|
|
#include <QFileDialog>
|
|
#include <QHBoxLayout>
|
|
#include <QProgressDialog>
|
|
#include <QPushButton>
|
|
#include <QVBoxLayout>
|
|
|
|
WalletView::WalletView(const PlatformStyle *platformStyle, QWidget *parent):
|
|
QStackedWidget(parent),
|
|
clientModel(0),
|
|
walletModel(0),
|
|
platformStyle(platformStyle)
|
|
{
|
|
// Create tabs
|
|
overviewPage = new OverviewPage(platformStyle);
|
|
|
|
transactionsPage = new QWidget(this);
|
|
QVBoxLayout *vbox = new QVBoxLayout();
|
|
QHBoxLayout *hbox_buttons = new QHBoxLayout();
|
|
transactionView = new TransactionView(platformStyle, this);
|
|
vbox->addWidget(transactionView);
|
|
QPushButton *exportButton = new QPushButton(tr("&Export"), this);
|
|
exportButton->setToolTip(tr("Export the data in the current tab to a file"));
|
|
if (platformStyle->getImagesOnButtons()) {
|
|
exportButton->setIcon(platformStyle->SingleColorIcon(":/icons/export"));
|
|
}
|
|
hbox_buttons->addStretch();
|
|
hbox_buttons->addWidget(exportButton);
|
|
vbox->addLayout(hbox_buttons);
|
|
transactionsPage->setLayout(vbox);
|
|
|
|
receiveCoinsPage = new ReceiveCoinsDialog(platformStyle);
|
|
sendCoinsPage = new SendCoinsDialog(platformStyle);
|
|
|
|
addWidget(overviewPage);
|
|
addWidget(transactionsPage);
|
|
addWidget(receiveCoinsPage);
|
|
addWidget(sendCoinsPage);
|
|
|
|
// Clicking on a transaction on the overview pre-selects the transaction on the transaction history page
|
|
connect(overviewPage, SIGNAL(transactionClicked(QModelIndex)), transactionView, SLOT(focusTransaction(QModelIndex)));
|
|
|
|
// Double-clicking on a transaction on the transaction history page shows details
|
|
connect(transactionView, SIGNAL(doubleClicked(QModelIndex)), transactionView, SLOT(showDetails()));
|
|
|
|
// Clicking on "Export" allows to export the transaction list
|
|
connect(exportButton, SIGNAL(clicked()), transactionView, SLOT(exportClicked()));
|
|
|
|
// Pass through messages from sendCoinsPage
|
|
connect(sendCoinsPage, SIGNAL(message(QString,QString,unsigned int)), this, SIGNAL(message(QString,QString,unsigned int)));
|
|
// Pass through messages from transactionView
|
|
connect(transactionView, SIGNAL(message(QString,QString,unsigned int)), this, SIGNAL(message(QString,QString,unsigned int)));
|
|
}
|
|
|
|
WalletView::~WalletView()
|
|
{
|
|
}
|
|
|
|
void WalletView::setBitcoinGUI(BitcoinGUI *gui)
|
|
{
|
|
if (gui)
|
|
{
|
|
// Clicking on a transaction on the overview page simply sends you to transaction history page
|
|
connect(overviewPage, SIGNAL(transactionClicked(QModelIndex)), 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)));
|
|
|
|
// Pass through transaction notifications
|
|
connect(this, SIGNAL(incomingTransaction(QString,int,CAmount,QString,QString,QString)), gui, SLOT(incomingTransaction(QString,int,CAmount,QString,QString,QString)));
|
|
}
|
|
}
|
|
|
|
void WalletView::setClientModel(ClientModel *clientModel)
|
|
{
|
|
this->clientModel = clientModel;
|
|
|
|
overviewPage->setClientModel(clientModel);
|
|
sendCoinsPage->setClientModel(clientModel);
|
|
}
|
|
|
|
void WalletView::setWalletModel(WalletModel *walletModel)
|
|
{
|
|
this->walletModel = walletModel;
|
|
|
|
// Put transaction list in tabs
|
|
transactionView->setModel(walletModel);
|
|
overviewPage->setWalletModel(walletModel);
|
|
receiveCoinsPage->setModel(walletModel);
|
|
sendCoinsPage->setModel(walletModel);
|
|
|
|
if (walletModel)
|
|
{
|
|
// Receive and pass through messages from wallet model
|
|
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)));
|
|
updateEncryptionStatus();
|
|
|
|
// Balloon pop-up for new transaction
|
|
connect(walletModel->getTransactionTableModel(), SIGNAL(rowsInserted(QModelIndex,int,int)),
|
|
this, SLOT(processNewTransaction(QModelIndex,int,int)));
|
|
|
|
// Ask for passphrase if needed
|
|
connect(walletModel, SIGNAL(requireUnlock()), this, SLOT(unlockWallet()));
|
|
|
|
// Show progress dialog
|
|
connect(walletModel, SIGNAL(showProgress(QString,int)), this, SLOT(showProgress(QString,int)));
|
|
}
|
|
}
|
|
|
|
void WalletView::processNewTransaction(const QModelIndex& parent, int start, int /*end*/)
|
|
{
|
|
// Prevent balloon-spam when initial block download is in progress
|
|
if (!walletModel || !clientModel || clientModel->inInitialBlockDownload())
|
|
return;
|
|
|
|
TransactionTableModel *ttm = walletModel->getTransactionTableModel();
|
|
if (!ttm || ttm->processingQueuedTransactions())
|
|
return;
|
|
|
|
QString date = ttm->index(start, TransactionTableModel::Date, parent).data().toString();
|
|
qint64 amount = ttm->index(start, TransactionTableModel::Amount, parent).data(Qt::EditRole).toULongLong();
|
|
QString type = ttm->index(start, TransactionTableModel::Type, parent).data().toString();
|
|
QModelIndex index = ttm->index(start, 0, parent);
|
|
QString address = ttm->data(index, TransactionTableModel::AddressRole).toString();
|
|
QString label = ttm->data(index, TransactionTableModel::LabelRole).toString();
|
|
|
|
emit incomingTransaction(date, walletModel->getOptionsModel()->getDisplayUnit(), amount, type, address, label);
|
|
}
|
|
|
|
void WalletView::gotoOverviewPage()
|
|
{
|
|
setCurrentWidget(overviewPage);
|
|
}
|
|
|
|
void WalletView::gotoHistoryPage()
|
|
{
|
|
setCurrentWidget(transactionsPage);
|
|
}
|
|
|
|
void WalletView::gotoReceiveCoinsPage()
|
|
{
|
|
setCurrentWidget(receiveCoinsPage);
|
|
}
|
|
|
|
void WalletView::gotoSendCoinsPage(QString addr)
|
|
{
|
|
setCurrentWidget(sendCoinsPage);
|
|
|
|
if (!addr.isEmpty())
|
|
sendCoinsPage->setAddress(addr);
|
|
}
|
|
|
|
void WalletView::gotoSignMessageTab(QString addr)
|
|
{
|
|
// calls show() in showTab_SM()
|
|
SignVerifyMessageDialog *signVerifyMessageDialog = new SignVerifyMessageDialog(platformStyle, this);
|
|
signVerifyMessageDialog->setAttribute(Qt::WA_DeleteOnClose);
|
|
signVerifyMessageDialog->setModel(walletModel);
|
|
signVerifyMessageDialog->showTab_SM(true);
|
|
|
|
if (!addr.isEmpty())
|
|
signVerifyMessageDialog->setAddress_SM(addr);
|
|
}
|
|
|
|
void WalletView::gotoVerifyMessageTab(QString addr)
|
|
{
|
|
// calls show() in showTab_VM()
|
|
SignVerifyMessageDialog *signVerifyMessageDialog = new SignVerifyMessageDialog(platformStyle, this);
|
|
signVerifyMessageDialog->setAttribute(Qt::WA_DeleteOnClose);
|
|
signVerifyMessageDialog->setModel(walletModel);
|
|
signVerifyMessageDialog->showTab_VM(true);
|
|
|
|
if (!addr.isEmpty())
|
|
signVerifyMessageDialog->setAddress_VM(addr);
|
|
}
|
|
|
|
bool WalletView::handlePaymentRequest(const SendCoinsRecipient& recipient)
|
|
{
|
|
return sendCoinsPage->handlePaymentRequest(recipient);
|
|
}
|
|
|
|
void WalletView::showOutOfSyncWarning(bool fShow)
|
|
{
|
|
overviewPage->showOutOfSyncWarning(fShow);
|
|
}
|
|
|
|
void WalletView::updateEncryptionStatus()
|
|
{
|
|
emit encryptionStatusChanged(walletModel->getEncryptionStatus());
|
|
}
|
|
|
|
void WalletView::encryptWallet(bool status)
|
|
{
|
|
if(!walletModel)
|
|
return;
|
|
AskPassphraseDialog dlg(status ? AskPassphraseDialog::Encrypt : AskPassphraseDialog::Decrypt, this);
|
|
dlg.setModel(walletModel);
|
|
dlg.exec();
|
|
|
|
updateEncryptionStatus();
|
|
}
|
|
|
|
void WalletView::backupWallet()
|
|
{
|
|
QString filename = GUIUtil::getSaveFileName(this,
|
|
tr("Backup Wallet"), QString(),
|
|
tr("Wallet Data (*.dat)"), NULL);
|
|
|
|
if (filename.isEmpty())
|
|
return;
|
|
|
|
if (!walletModel->backupWallet(filename)) {
|
|
emit message(tr("Backup Failed"), tr("There was an error trying to save the wallet data to %1.").arg(filename),
|
|
CClientUIInterface::MSG_ERROR);
|
|
}
|
|
else {
|
|
emit message(tr("Backup Successful"), tr("The wallet data was successfully saved to %1.").arg(filename),
|
|
CClientUIInterface::MSG_INFORMATION);
|
|
}
|
|
}
|
|
|
|
void WalletView::changePassphrase()
|
|
{
|
|
AskPassphraseDialog dlg(AskPassphraseDialog::ChangePass, this);
|
|
dlg.setModel(walletModel);
|
|
dlg.exec();
|
|
}
|
|
|
|
void WalletView::unlockWallet()
|
|
{
|
|
if(!walletModel)
|
|
return;
|
|
// Unlock wallet when requested by wallet model
|
|
if (walletModel->getEncryptionStatus() == WalletModel::Locked)
|
|
{
|
|
AskPassphraseDialog dlg(AskPassphraseDialog::Unlock, this);
|
|
dlg.setModel(walletModel);
|
|
dlg.exec();
|
|
}
|
|
}
|
|
|
|
void WalletView::usedSendingAddresses()
|
|
{
|
|
if(!walletModel)
|
|
return;
|
|
AddressBookPage *dlg = new AddressBookPage(platformStyle, AddressBookPage::ForEditing, AddressBookPage::SendingTab, this);
|
|
dlg->setAttribute(Qt::WA_DeleteOnClose);
|
|
dlg->setModel(walletModel->getAddressTableModel());
|
|
dlg->show();
|
|
}
|
|
|
|
void WalletView::usedReceivingAddresses()
|
|
{
|
|
if(!walletModel)
|
|
return;
|
|
AddressBookPage *dlg = new AddressBookPage(platformStyle, AddressBookPage::ForEditing, AddressBookPage::ReceivingTab, this);
|
|
dlg->setAttribute(Qt::WA_DeleteOnClose);
|
|
dlg->setModel(walletModel->getAddressTableModel());
|
|
dlg->show();
|
|
}
|
|
|
|
void WalletView::showProgress(const QString &title, int nProgress)
|
|
{
|
|
if (nProgress == 0)
|
|
{
|
|
progressDialog = new QProgressDialog(title, "", 0, 100);
|
|
progressDialog->setWindowModality(Qt::ApplicationModal);
|
|
progressDialog->setMinimumDuration(0);
|
|
progressDialog->setCancelButton(0);
|
|
progressDialog->setAutoClose(false);
|
|
progressDialog->setValue(0);
|
|
}
|
|
else if (nProgress == 100)
|
|
{
|
|
if (progressDialog)
|
|
{
|
|
progressDialog->close();
|
|
progressDialog->deleteLater();
|
|
}
|
|
}
|
|
else if (progressDialog)
|
|
progressDialog->setValue(nProgress);
|
|
}
|
|
|
|
void WalletView::printPaperWallets()
|
|
{
|
|
if(!walletModel)
|
|
return;
|
|
|
|
PaperWalletDialog dlg(this);
|
|
dlg.setModel(walletModel);
|
|
dlg.exec();
|
|
}
|