You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

274 lines
8.8 KiB

/*
* Qt4 bitcoin GUI.
*
* W.J. van der Laan 2011-2012
* The Bitcoin Developers 2011-2013
*/
#include "walletview.h"
#include "bitcoingui.h"
#include "transactiontablemodel.h"
#include "addressbookpage.h"
#include "sendcoinsdialog.h"
#include "signverifymessagedialog.h"
#include "clientmodel.h"
#include "walletmodel.h"
#include "optionsmodel.h"
#include "transactionview.h"
#include "overviewpage.h"
#include "askpassphrasedialog.h"
#include "ui_interface.h"
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QAction>
#if QT_VERSION < 0x050000
#include <QDesktopServices>
#else
#include <QStandardPaths>
#endif
#include <QFileDialog>
#include <QPushButton>
WalletView::WalletView(QWidget *parent, BitcoinGUI *_gui):
QStackedWidget(parent),
gui(_gui),
clientModel(0),
walletModel(0)
{
// Create tabs
overviewPage = new OverviewPage();
transactionsPage = new QWidget(this);
QVBoxLayout *vbox = new QVBoxLayout();
QHBoxLayout *hbox_buttons = new QHBoxLayout();
transactionView = new TransactionView(this);
vbox->addWidget(transactionView);
QPushButton *exportButton = new QPushButton(tr("&Export"), this);
exportButton->setToolTip(tr("Export the data in the current tab to a file"));
#ifndef Q_OS_MAC // Icons on push buttons are very uncommon on Mac
exportButton->setIcon(QIcon(":/icons/export"));
#endif
hbox_buttons->addStretch();
hbox_buttons->addWidget(exportButton);
vbox->addLayout(hbox_buttons);
transactionsPage->setLayout(vbox);
addressBookPage = new AddressBookPage(AddressBookPage::ForEditing, AddressBookPage::SendingTab);
receiveCoinsPage = new AddressBookPage(AddressBookPage::ForEditing, AddressBookPage::ReceivingTab);
sendCoinsPage = new SendCoinsDialog(gui);
signVerifyMessageDialog = new SignVerifyMessageDialog(gui);
addWidget(overviewPage);
addWidget(transactionsPage);
addWidget(addressBookPage);
addWidget(receiveCoinsPage);
addWidget(sendCoinsPage);
// Clicking on a transaction on the overview page simply sends you to transaction history page
connect(overviewPage, SIGNAL(transactionClicked(QModelIndex)), this, SLOT(gotoHistoryPage()));
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 "Send Coins" in the address book sends you to the send coins tab
connect(addressBookPage, SIGNAL(sendCoins(QString)), this, SLOT(gotoSendCoinsPage(QString)));
// Clicking on "Verify Message" in the address book opens the verify message tab in the Sign/Verify Message dialog
connect(addressBookPage, SIGNAL(verifyMessage(QString)), this, SLOT(gotoVerifyMessageTab(QString)));
// Clicking on "Sign Message" in the receive coins page opens the sign message tab in the Sign/Verify Message dialog
connect(receiveCoinsPage, SIGNAL(signMessage(QString)), this, SLOT(gotoSignMessageTab(QString)));
// Clicking on "Export" allows to export the transaction list
connect(exportButton, SIGNAL(clicked()), transactionView, SLOT(exportClicked()));
gotoOverviewPage();
}
WalletView::~WalletView()
{
}
void WalletView::setBitcoinGUI(BitcoinGUI *gui)
{
this->gui = gui;
}
void WalletView::setClientModel(ClientModel *clientModel)
{
this->clientModel = clientModel;
if (clientModel)
{
overviewPage->setClientModel(clientModel);
addressBookPage->setOptionsModel(clientModel->getOptionsModel());
receiveCoinsPage->setOptionsModel(clientModel->getOptionsModel());
}
}
void WalletView::setWalletModel(WalletModel *walletModel)
{
this->walletModel = walletModel;
if (walletModel)
{
// Receive and report messages from wallet thread
connect(walletModel, SIGNAL(message(QString,QString,unsigned int)), gui, SLOT(message(QString,QString,unsigned int)));
// Put transaction list in tabs
transactionView->setModel(walletModel);
overviewPage->setWalletModel(walletModel);
addressBookPage->setModel(walletModel->getAddressTableModel());
receiveCoinsPage->setModel(walletModel->getAddressTableModel());
sendCoinsPage->setModel(walletModel);
signVerifyMessageDialog->setModel(walletModel);
setEncryptionStatus();
connect(walletModel, SIGNAL(encryptionStatusChanged(int)), gui, SLOT(setEncryptionStatus(int)));
// Balloon pop-up for new transaction
connect(walletModel->getTransactionTableModel(), SIGNAL(rowsInserted(QModelIndex,int,int)),
this, SLOT(incomingTransaction(QModelIndex,int,int)));
// Ask for passphrase if needed
connect(walletModel, SIGNAL(requireUnlock()), this, SLOT(unlockWallet()));
}
}
void WalletView::incomingTransaction(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();
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();
QString address = ttm->index(start, TransactionTableModel::ToAddress, parent).data().toString();
gui->incomingTransaction(date, walletModel->getOptionsModel()->getDisplayUnit(), amount, type, address);
}
void WalletView::gotoOverviewPage()
{
gui->getOverviewAction()->setChecked(true);
setCurrentWidget(overviewPage);
}
void WalletView::gotoHistoryPage()
{
gui->getHistoryAction()->setChecked(true);
setCurrentWidget(transactionsPage);
}
void WalletView::gotoAddressBookPage()
{
gui->getAddressBookAction()->setChecked(true);
setCurrentWidget(addressBookPage);
}
void WalletView::gotoReceiveCoinsPage()
{
gui->getReceiveCoinsAction()->setChecked(true);
setCurrentWidget(receiveCoinsPage);
}
void WalletView::gotoSendCoinsPage(QString addr)
{
gui->getSendCoinsAction()->setChecked(true);
setCurrentWidget(sendCoinsPage);
if (!addr.isEmpty())
sendCoinsPage->setAddress(addr);
}
void WalletView::gotoSignMessageTab(QString addr)
{
// call show() in showTab_SM()
signVerifyMessageDialog->showTab_SM(true);
if (!addr.isEmpty())
signVerifyMessageDialog->setAddress_SM(addr);
}
void WalletView::gotoVerifyMessageTab(QString addr)
{
// call show() in showTab_VM()
signVerifyMessageDialog->showTab_VM(true);
if (!addr.isEmpty())
signVerifyMessageDialog->setAddress_VM(addr);
}
bool WalletView::handleURI(const QString& strURI)
{
// URI has to be valid
if (sendCoinsPage->handleURI(strURI))
{
gotoSendCoinsPage();
return true;
}
else
return false;
}
void WalletView::showOutOfSyncWarning(bool fShow)
{
overviewPage->showOutOfSyncWarning(fShow);
}
void WalletView::setEncryptionStatus()
{
gui->setEncryptionStatus(walletModel->getEncryptionStatus());
}
void WalletView::encryptWallet(bool status)
{
if(!walletModel)
return;
AskPassphraseDialog dlg(status ? AskPassphraseDialog::Encrypt : AskPassphraseDialog::Decrypt, this);
dlg.setModel(walletModel);
dlg.exec();
setEncryptionStatus();
}
void WalletView::backupWallet()
{
#if QT_VERSION < 0x050000
QString saveDir = QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation);
#else
QString saveDir = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
#endif
QString filename = QFileDialog::getSaveFileName(this, tr("Backup Wallet"), saveDir, tr("Wallet Data (*.dat)"));
if (!filename.isEmpty()) {
if (!walletModel->backupWallet(filename)) {
gui->message(tr("Backup Failed"), tr("There was an error trying to save the wallet data to the new location."),
CClientUIInterface::MSG_ERROR);
}
else
gui->message(tr("Backup Successful"), tr("The wallet data was successfully saved to the new location."),
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();
}
}