Merge remote-tracking branch 'codeshark/multiwallet-qt-no-core' (pull #2220)

Conflicts:
	src/qt/bitcoingui.cpp
This commit is contained in:
Wladimir J. van der Laan
2013-03-29 09:54:00 +01:00
11 changed files with 1097 additions and 226 deletions

View File

@@ -10,26 +10,20 @@
#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 "walletframe.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 "notificator.h"
#include "guiutil.h"
#include "rpcconsole.h"
#include "ui_interface.h"
#include "wallet.h"
#ifdef Q_OS_MAC
#include "macdockiconhandler.h"
@@ -56,13 +50,15 @@
#include <QStyle>
#include <QSettings>
#include <QDesktopWidget>
#include <QListWidget>
#include <iostream>
const QString BitcoinGUI::DEFAULT_WALLET = "~Default";
BitcoinGUI::BitcoinGUI(QWidget *parent):
QMainWindow(parent),
clientModel(0),
walletModel(0),
encryptWalletAction(0),
changePassphraseAction(0),
aboutQtAction(0),
@@ -95,31 +91,10 @@ BitcoinGUI::BitcoinGUI(QWidget *parent):
// Create system tray icon and notification
createTrayIcon();
// 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(this);
signVerifyMessageDialog = new SignVerifyMessageDialog(this);
centralWidget = new QStackedWidget(this);
centralWidget->addWidget(overviewPage);
centralWidget->addWidget(transactionsPage);
centralWidget->addWidget(addressBookPage);
centralWidget->addWidget(receiveCoinsPage);
centralWidget->addWidget(sendCoinsPage);
setCentralWidget(centralWidget);
// Create wallet frame and make it the central widget
walletFrame = new WalletFrame(this);
setCentralWidget(walletFrame);
// Create status bar
statusBar();
@@ -164,27 +139,11 @@ BitcoinGUI::BitcoinGUI(QWidget *parent):
syncIconMovie = new QMovie(":/movies/update_spinner", "mng", this);
// 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()));
rpcConsole = new RPCConsole(this);
connect(openRPCConsoleAction, SIGNAL(triggered()), rpcConsole, SLOT(show()));
// 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)));
// Install event filter to be able to catch status tip events (QEvent::StatusTip)
this->installEventFilter(this);
gotoOverviewPage();
}
BitcoinGUI::~BitcoinGUI()
@@ -246,7 +205,7 @@ void BitcoinGUI::createActions()
connect(historyAction, SIGNAL(triggered()), this, SLOT(gotoHistoryPage()));
connect(addressBookAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
connect(addressBookAction, SIGNAL(triggered()), this, SLOT(gotoAddressBookPage()));
quitAction = new QAction(QIcon(":/icons/quit"), tr("E&xit"), this);
quitAction->setStatusTip(tr("Quit application"));
quitAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q));
@@ -380,39 +339,23 @@ void BitcoinGUI::setClientModel(ClientModel *clientModel)
// Receive and report messages from network/worker thread
connect(clientModel, SIGNAL(message(QString,QString,unsigned int)), this, SLOT(message(QString,QString,unsigned int)));
overviewPage->setClientModel(clientModel);
rpcConsole->setClientModel(clientModel);
addressBookPage->setOptionsModel(clientModel->getOptionsModel());
receiveCoinsPage->setOptionsModel(clientModel->getOptionsModel());
walletFrame->setClientModel(clientModel);
}
}
void BitcoinGUI::setWalletModel(WalletModel *walletModel)
bool BitcoinGUI::addWallet(const QString& name, WalletModel *walletModel)
{
this->walletModel = walletModel;
if(walletModel)
{
// Receive and report messages from wallet thread
connect(walletModel, SIGNAL(message(QString,QString,unsigned int)), this, SLOT(message(QString,QString,unsigned int)));
return walletFrame->addWallet(name, walletModel);
}
// 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);
bool BitcoinGUI::setCurrentWallet(const QString& name)
{
return walletFrame->setCurrentWallet(name);
}
setEncryptionStatus(walletModel->getEncryptionStatus());
connect(walletModel, SIGNAL(encryptionStatusChanged(int)), this, 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 BitcoinGUI::removeAllWallets()
{
walletFrame->removeAllWallets();
}
void BitcoinGUI::createTrayIcon()
@@ -509,6 +452,41 @@ void BitcoinGUI::aboutClicked()
dlg.exec();
}
void BitcoinGUI::gotoOverviewPage()
{
if (walletFrame) walletFrame->gotoOverviewPage();
}
void BitcoinGUI::gotoHistoryPage()
{
if (walletFrame) walletFrame->gotoHistoryPage();
}
void BitcoinGUI::gotoAddressBookPage()
{
if (walletFrame) walletFrame->gotoAddressBookPage();
}
void BitcoinGUI::gotoReceiveCoinsPage()
{
if (walletFrame) walletFrame->gotoReceiveCoinsPage();
}
void BitcoinGUI::gotoSendCoinsPage()
{
if (walletFrame) walletFrame->gotoSendCoinsPage();
}
void BitcoinGUI::gotoSignMessageTab(QString addr)
{
if (walletFrame) walletFrame->gotoSignMessageTab(addr);
}
void BitcoinGUI::gotoVerifyMessageTab(QString addr)
{
if (walletFrame) walletFrame->gotoSignMessageTab(addr);
}
void BitcoinGUI::setNumConnections(int count)
{
QString icon;
@@ -573,7 +551,7 @@ void BitcoinGUI::setNumBlocks(int count, int nTotalBlocks)
tooltip = tr("Up to date") + QString(".<br>") + tooltip;
labelBlocksIcon->setPixmap(QIcon(":/icons/synced").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
overviewPage->showOutOfSyncWarning(false);
walletFrame->showOutOfSyncWarning(false);
progressBarLabel->setVisible(false);
progressBar->setVisible(false);
@@ -608,7 +586,7 @@ void BitcoinGUI::setNumBlocks(int count, int nTotalBlocks)
syncIconMovie->jumpToNextFrame();
prevBlocks = count;
overviewPage->showOutOfSyncWarning(true);
walletFrame->showOutOfSyncWarning(true);
tooltip += QString("<br>");
tooltip += tr("Last received block was generated %1 ago.").arg(timeBehindText);
@@ -717,104 +695,20 @@ void BitcoinGUI::askFee(qint64 nFeeRequired, bool *payFee)
*payFee = (retval == QMessageBox::Yes);
}
void BitcoinGUI::incomingTransaction(const QModelIndex& parent, int start, int /*end*/)
void BitcoinGUI::incomingTransaction(const QString& date, int unit, qint64 amount, const QString& type, const QString& address)
{
// 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();
// On new transaction, make an info balloon
// On new transaction, make an info balloon
message((amount)<0 ? tr("Sent transaction") : tr("Incoming transaction"),
tr("Date: %1\n"
"Amount: %2\n"
"Type: %3\n"
"Address: %4\n")
.arg(date)
.arg(BitcoinUnits::formatWithUnit(walletModel->getOptionsModel()->getDisplayUnit(), amount, true))
.arg(BitcoinUnits::formatWithUnit(unit, amount, true))
.arg(type)
.arg(address), CClientUIInterface::MSG_INFORMATION);
}
void BitcoinGUI::gotoOverviewPage()
{
overviewAction->setChecked(true);
centralWidget->setCurrentWidget(overviewPage);
exportAction->setEnabled(false);
disconnect(exportAction, SIGNAL(triggered()), 0, 0);
}
void BitcoinGUI::gotoHistoryPage()
{
historyAction->setChecked(true);
centralWidget->setCurrentWidget(transactionsPage);
exportAction->setEnabled(true);
disconnect(exportAction, SIGNAL(triggered()), 0, 0);
connect(exportAction, SIGNAL(triggered()), transactionView, SLOT(exportClicked()));
}
void BitcoinGUI::gotoAddressBookPage()
{
addressBookAction->setChecked(true);
centralWidget->setCurrentWidget(addressBookPage);
exportAction->setEnabled(true);
disconnect(exportAction, SIGNAL(triggered()), 0, 0);
connect(exportAction, SIGNAL(triggered()), addressBookPage, SLOT(exportClicked()));
}
void BitcoinGUI::gotoReceiveCoinsPage()
{
receiveCoinsAction->setChecked(true);
centralWidget->setCurrentWidget(receiveCoinsPage);
exportAction->setEnabled(true);
disconnect(exportAction, SIGNAL(triggered()), 0, 0);
connect(exportAction, SIGNAL(triggered()), receiveCoinsPage, SLOT(exportClicked()));
}
void BitcoinGUI::gotoSendCoinsPage(QString addr)
{
sendCoinsAction->setChecked(true);
centralWidget->setCurrentWidget(sendCoinsPage);
exportAction->setEnabled(false);
disconnect(exportAction, SIGNAL(triggered()), 0, 0);
if(!addr.isEmpty())
sendCoinsPage->setAddress(addr);
}
void BitcoinGUI::gotoSignMessageTab(QString addr)
{
// call show() in showTab_SM()
signVerifyMessageDialog->showTab_SM(true);
if(!addr.isEmpty())
signVerifyMessageDialog->setAddress_SM(addr);
}
void BitcoinGUI::gotoVerifyMessageTab(QString addr)
{
// call show() in showTab_VM()
signVerifyMessageDialog->showTab_VM(true);
if(!addr.isEmpty())
signVerifyMessageDialog->setAddress_VM(addr);
}
void BitcoinGUI::dragEnterEvent(QDragEnterEvent *event)
{
// Accept only URIs
@@ -830,13 +724,13 @@ void BitcoinGUI::dropEvent(QDropEvent *event)
QList<QUrl> uris = event->mimeData()->urls();
foreach(const QUrl &uri, uris)
{
if (sendCoinsPage->handleURI(uri.toString()))
if (walletFrame->handleURI(uri.toString()))
nValidUrisFound++;
}
// if valid URIs were found
if (nValidUrisFound)
gotoSendCoinsPage();
walletFrame->gotoSendCoinsPage();
else
message(tr("URI handling"), tr("URI can not be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters."),
CClientUIInterface::ICON_WARNING);
@@ -860,12 +754,7 @@ bool BitcoinGUI::eventFilter(QObject *object, QEvent *event)
void BitcoinGUI::handleURI(QString strURI)
{
// URI has to be valid
if (sendCoinsPage->handleURI(strURI))
{
showNormalIfMinimized();
gotoSendCoinsPage();
}
else
if (!walletFrame->handleURI(strURI))
message(tr("URI handling"), tr("URI can not be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters."),
CClientUIInterface::ICON_WARNING);
}
@@ -901,49 +790,22 @@ void BitcoinGUI::setEncryptionStatus(int status)
void BitcoinGUI::encryptWallet(bool status)
{
if(!walletModel)
return;
AskPassphraseDialog dlg(status ? AskPassphraseDialog::Encrypt:
AskPassphraseDialog::Decrypt, this);
dlg.setModel(walletModel);
dlg.exec();
setEncryptionStatus(walletModel->getEncryptionStatus());
walletFrame->encryptWallet(status);
}
void BitcoinGUI::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)) {
message(tr("Backup Failed"), tr("There was an error trying to save the wallet data to the new location."),
CClientUIInterface::MSG_ERROR);
}
else
message(tr("Backup Successful"), tr("The wallet data was successfully saved to the new location."),
CClientUIInterface::MSG_INFORMATION);
}
walletFrame->backupWallet();
}
void BitcoinGUI::changePassphrase()
{
AskPassphraseDialog dlg(AskPassphraseDialog::ChangePass, this);
dlg.setModel(walletModel);
dlg.exec();
walletFrame->changePassphrase();
}
void BitcoinGUI::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();
}
walletFrame->unlockWallet();
}
void BitcoinGUI::showNormalIfMinimized(bool fToggleHidden)