aboutsummaryrefslogtreecommitdiff
path: root/src/qt/walletview.cpp
diff options
context:
space:
mode:
authorEric Lombrozo <elombrozo@gmail.com>2013-03-22 10:32:49 -0700
committerEric Lombrozo <elombrozo@gmail.com>2013-03-22 11:09:08 -0700
commit67155d9299ef75cc73272a259dbfbf72632c3020 (patch)
treee351256ef8c01d40654ef06b40551c9602f31158 /src/qt/walletview.cpp
parentdfd71bb4509d12c26e630bc671a542ad5bab4945 (diff)
Minimal architectural changes necessary to support multiple wallets in bitcoin-qt
- This commit is a minimal restructuring necessary to support multiple wallets in the UI. Please see multiwallet-qt.txt for details.
Diffstat (limited to 'src/qt/walletview.cpp')
-rw-r--r--src/qt/walletview.cpp354
1 files changed, 354 insertions, 0 deletions
diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp
new file mode 100644
index 0000000000..7dd36234c9
--- /dev/null
+++ b/src/qt/walletview.cpp
@@ -0,0 +1,354 @@
+/*
+ * 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 "optionsdialog.h"
+#include "aboutdialog.h"
+#include "clientmodel.h"
+#include "walletmodel.h"
+#include "editaddressdialog.h"
+#include "optionsmodel.h"
+#include "transactiondescdialog.h"
+#include "addresstablemodel.h"
+#include "transactionview.h"
+#include "overviewpage.h"
+#include "bitcoinunits.h"
+#include "guiconstants.h"
+#include "askpassphrasedialog.h"
+#include "guiutil.h"
+#include "ui_interface.h"
+
+#include <QVBoxLayout>
+#include <QActionGroup>
+#include <QAction>
+#include <QLabel>
+#include <QDesktopServices>
+#include <QFileDialog>
+
+WalletView::WalletView(QWidget *parent, BitcoinGUI *_gui):
+ QStackedWidget(parent),
+ gui(_gui),
+ clientModel(0),
+ walletModel(0),
+ encryptWalletAction(0),
+ changePassphraseAction(0)
+{
+ // Create actions for the toolbar, menu bar and tray/dock icon
+ createActions();
+
+ // Create tabs
+ overviewPage = new OverviewPage();
+
+ transactionsPage = new QWidget(this);
+ QVBoxLayout *vbox = new QVBoxLayout();
+ transactionView = new TransactionView(this);
+ vbox->addWidget(transactionView);
+ 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 "Verify Message" in the address book sends you to the verify message tab
+ connect(addressBookPage, SIGNAL(verifyMessage(QString)), this, SLOT(gotoVerifyMessageTab(QString)));
+ // Clicking on "Sign Message" in the receive coins page sends you to the sign message tab
+ connect(receiveCoinsPage, SIGNAL(signMessage(QString)), this, SLOT(gotoSignMessageTab(QString)));
+
+ gotoOverviewPage();
+}
+
+WalletView::~WalletView()
+{
+}
+
+void WalletView::createActions()
+{
+ QActionGroup *tabGroup = new QActionGroup(this);
+
+ overviewAction = new QAction(QIcon(":/icons/overview"), tr("&Overview"), this);
+ overviewAction->setStatusTip(tr("Show general overview of wallet"));
+ overviewAction->setToolTip(overviewAction->statusTip());
+ overviewAction->setCheckable(true);
+ overviewAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_1));
+ tabGroup->addAction(overviewAction);
+
+ sendCoinsAction = new QAction(QIcon(":/icons/send"), tr("&Send coins"), this);
+ sendCoinsAction->setStatusTip(tr("Send coins to a Bitcoin address"));
+ sendCoinsAction->setToolTip(sendCoinsAction->statusTip());
+ sendCoinsAction->setCheckable(true);
+ sendCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_2));
+ tabGroup->addAction(sendCoinsAction);
+
+ receiveCoinsAction = new QAction(QIcon(":/icons/receiving_addresses"), tr("&Receive coins"), this);
+ receiveCoinsAction->setStatusTip(tr("Show the list of addresses for receiving payments"));
+ receiveCoinsAction->setToolTip(receiveCoinsAction->statusTip());
+ receiveCoinsAction->setCheckable(true);
+ receiveCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_3));
+ tabGroup->addAction(receiveCoinsAction);
+
+ historyAction = new QAction(QIcon(":/icons/history"), tr("&Transactions"), this);
+ historyAction->setStatusTip(tr("Browse transaction history"));
+ historyAction->setToolTip(historyAction->statusTip());
+ historyAction->setCheckable(true);
+ historyAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_4));
+ tabGroup->addAction(historyAction);
+
+ addressBookAction = new QAction(QIcon(":/icons/address-book"), tr("&Address Book"), this);
+ addressBookAction->setStatusTip(tr("Edit the list of stored addresses and labels"));
+ addressBookAction->setToolTip(addressBookAction->statusTip());
+ addressBookAction->setCheckable(true);
+ addressBookAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_5));
+ tabGroup->addAction(addressBookAction);
+
+ connect(overviewAction, SIGNAL(triggered()), this, SLOT(gotoOverviewPage()));
+ connect(sendCoinsAction, SIGNAL(triggered()), this, SLOT(gotoSendCoinsPage()));
+ connect(receiveCoinsAction, SIGNAL(triggered()), this, SLOT(gotoReceiveCoinsPage()));
+ connect(historyAction, SIGNAL(triggered()), this, SLOT(gotoHistoryPage()));
+ connect(addressBookAction, SIGNAL(triggered()), this, SLOT(gotoAddressBookPage()));
+
+ encryptWalletAction = new QAction(QIcon(":/icons/lock_closed"), tr("&Encrypt Wallet..."), this);
+ encryptWalletAction->setStatusTip(tr("Encrypt the private keys that belong to your wallet"));
+ encryptWalletAction->setCheckable(true);
+ backupWalletAction = new QAction(QIcon(":/icons/filesave"), tr("&Backup Wallet..."), this);
+ backupWalletAction->setStatusTip(tr("Backup wallet to another location"));
+ changePassphraseAction = new QAction(QIcon(":/icons/key"), tr("&Change Passphrase..."), this);
+ changePassphraseAction->setStatusTip(tr("Change the passphrase used for wallet encryption"));
+ signMessageAction = new QAction(QIcon(":/icons/edit"), tr("Sign &message..."), this);
+ signMessageAction->setStatusTip(tr("Sign messages with your Bitcoin addresses to prove you own them"));
+ verifyMessageAction = new QAction(QIcon(":/icons/transaction_0"), tr("&Verify message..."), this);
+ verifyMessageAction->setStatusTip(tr("Verify messages to ensure they were signed with specified Bitcoin addresses"));
+
+ exportAction = new QAction(QIcon(":/icons/export"), tr("&Export..."), this);
+ exportAction->setStatusTip(tr("Export the data in the current tab to a file"));
+ exportAction->setToolTip(exportAction->statusTip());
+
+ connect(encryptWalletAction, SIGNAL(triggered(bool)), this, SLOT(encryptWallet(bool)));
+ connect(backupWalletAction, SIGNAL(triggered()), this, SLOT(backupWallet()));
+ connect(changePassphraseAction, SIGNAL(triggered()), this, SLOT(changePassphrase()));
+ connect(signMessageAction, SIGNAL(triggered()), this, SLOT(gotoSignMessageTab()));
+ connect(verifyMessageAction, SIGNAL(triggered()), this, SLOT(gotoVerifyMessageTab()));
+}
+
+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()
+{
+ overviewAction->setChecked(true);
+ setCurrentWidget(overviewPage);
+
+ exportAction->setEnabled(false);
+ disconnect(exportAction, SIGNAL(triggered()), 0, 0);
+}
+
+void WalletView::gotoHistoryPage()
+{
+ historyAction->setChecked(true);
+ setCurrentWidget(transactionsPage);
+
+ exportAction->setEnabled(true);
+ disconnect(exportAction, SIGNAL(triggered()), 0, 0);
+ connect(exportAction, SIGNAL(triggered()), transactionView, SLOT(exportClicked()));
+}
+
+void WalletView::gotoAddressBookPage()
+{
+ addressBookAction->setChecked(true);
+ setCurrentWidget(addressBookPage);
+
+ exportAction->setEnabled(true);
+ disconnect(exportAction, SIGNAL(triggered()), 0, 0);
+ connect(exportAction, SIGNAL(triggered()), addressBookPage, SLOT(exportClicked()));
+}
+
+void WalletView::gotoReceiveCoinsPage()
+{
+ receiveCoinsAction->setChecked(true);
+ setCurrentWidget(receiveCoinsPage);
+
+ exportAction->setEnabled(true);
+ disconnect(exportAction, SIGNAL(triggered()), 0, 0);
+ connect(exportAction, SIGNAL(triggered()), receiveCoinsPage, SLOT(exportClicked()));
+}
+
+void WalletView::gotoSendCoinsPage()
+{
+ sendCoinsAction->setChecked(true);
+ setCurrentWidget(sendCoinsPage);
+
+ exportAction->setEnabled(false);
+ disconnect(exportAction, SIGNAL(triggered()), 0, 0);
+}
+
+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()
+{
+ QString saveDir = QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation);
+ 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();
+ }
+}