Merge remote-tracking branch 'codeshark/multiwallet-qt-no-core' (pull #2220)
Conflicts: src/qt/bitcoingui.cpp
This commit is contained in:
commit
a6d32c94ab
11 changed files with 1097 additions and 226 deletions
|
@ -186,6 +186,9 @@ HEADERS += src/qt/bitcoingui.h \
|
||||||
src/qt/transactionfilterproxy.h \
|
src/qt/transactionfilterproxy.h \
|
||||||
src/qt/transactionview.h \
|
src/qt/transactionview.h \
|
||||||
src/qt/walletmodel.h \
|
src/qt/walletmodel.h \
|
||||||
|
src/qt/walletview.h \
|
||||||
|
src/qt/walletstack.h \
|
||||||
|
src/qt/walletframe.h \
|
||||||
src/bitcoinrpc.h \
|
src/bitcoinrpc.h \
|
||||||
src/qt/overviewpage.h \
|
src/qt/overviewpage.h \
|
||||||
src/qt/csvmodelwriter.h \
|
src/qt/csvmodelwriter.h \
|
||||||
|
@ -250,6 +253,9 @@ SOURCES += src/qt/bitcoin.cpp \
|
||||||
src/qt/transactionfilterproxy.cpp \
|
src/qt/transactionfilterproxy.cpp \
|
||||||
src/qt/transactionview.cpp \
|
src/qt/transactionview.cpp \
|
||||||
src/qt/walletmodel.cpp \
|
src/qt/walletmodel.cpp \
|
||||||
|
src/qt/walletview.cpp \
|
||||||
|
src/qt/walletstack.cpp \
|
||||||
|
src/qt/walletframe.cpp \
|
||||||
src/bitcoinrpc.cpp \
|
src/bitcoinrpc.cpp \
|
||||||
src/rpcdump.cpp \
|
src/rpcdump.cpp \
|
||||||
src/rpcnet.cpp \
|
src/rpcnet.cpp \
|
||||||
|
|
53
multiwallet-qt.txt
Normal file
53
multiwallet-qt.txt
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
Multiwallet Qt Development and Integration Strategy
|
||||||
|
===================================================
|
||||||
|
|
||||||
|
In order to support loading of multiple wallets in bitcoin-qt, a few changes in the UI architecture will be needed.
|
||||||
|
Fortunately, only four of the files in the existing project are affected by this change.
|
||||||
|
|
||||||
|
Three new classes have been implemented in three new .h/.cpp file pairs, with much of the functionality that was previously
|
||||||
|
implemented in the BitcoinGUI class moved over to these new classes.
|
||||||
|
|
||||||
|
The two existing files most affected, by far, are bitcoingui.h and bitcoingui.cpp, as the BitcoinGUI class will require
|
||||||
|
some major retrofitting.
|
||||||
|
|
||||||
|
Only requiring some minor changes is bitcoin.cpp.
|
||||||
|
|
||||||
|
Finally, three new headers and source files will have to be added to bitcoin-qt.pro.
|
||||||
|
|
||||||
|
Changes to class BitcoinGUI
|
||||||
|
---------------------------
|
||||||
|
The principal change to the BitcoinGUI class concerns the QStackedWidget instance called centralWidget.
|
||||||
|
This widget owns five page views: overviewPage, transactionsPage, addressBookPage, receiveCoinsPage, and sendCoinsPage.
|
||||||
|
|
||||||
|
A new class called *WalletView* inheriting from QStackedWidget has been written to handle all renderings and updates of
|
||||||
|
these page views. In addition to owning these five page views, a WalletView also has a pointer to a WalletModel instance.
|
||||||
|
This allows the construction of multiple WalletView objects, each rendering a distinct wallet.
|
||||||
|
|
||||||
|
A second class called *WalletStack*, also inheriting from QStackedWidget, has been written to handle switching focus between
|
||||||
|
different loaded wallets. In its current implementation, as a QStackedWidget, only one wallet can be viewed at a time -
|
||||||
|
but this can be changed later.
|
||||||
|
|
||||||
|
A third class called *WalletFrame* inheriting from QFrame has been written as a container for embedding all wallet-related
|
||||||
|
controls into BitcoinGUI. At present it just contains a WalletStack instance and does little more than passing on messages
|
||||||
|
from BitcoinGUI to the WalletStack, which in turn passes them to the individual WalletViews. It is a WalletFrame instance
|
||||||
|
that takes the place of what used to be centralWidget in BitcoinGUI. The purpose of this class is to allow future
|
||||||
|
refinements of the wallet controls with minimal need for further modifications to BitcoinGUI, thus greatly simplifying
|
||||||
|
merges while reducing the risk of breaking top-level stuff.
|
||||||
|
|
||||||
|
Changes to bitcoin.cpp
|
||||||
|
----------------------
|
||||||
|
bitcoin.cpp is the entry point into bitcoin-qt, and as such, will require some minor modifications to provide hooks for
|
||||||
|
multiple wallet support. Most importantly will be the way it instantiates WalletModels and passes them to the
|
||||||
|
singleton BitcoinGUI instance called window. Formerly, BitcoinGUI kept a pointer to a single instance of a WalletModel.
|
||||||
|
The initial change required is very simple: rather than calling window.setWalletModel(&walletModel); we perform the
|
||||||
|
following two steps:
|
||||||
|
|
||||||
|
window.addWallet("~Default", &walletModel);
|
||||||
|
window.setCurrentWallet("~Default");
|
||||||
|
|
||||||
|
The string parameter is just an arbitrary name given to the default wallet. It's been prepended with a tilde to avoid name
|
||||||
|
collisions in the future with additional wallets.
|
||||||
|
|
||||||
|
The shutdown call window.setWalletModel(0) has also been removed. In its place is now:
|
||||||
|
|
||||||
|
window.removeAllWallets();
|
|
@ -232,7 +232,8 @@ int main(int argc, char *argv[])
|
||||||
WalletModel walletModel(pwalletMain, &optionsModel);
|
WalletModel walletModel(pwalletMain, &optionsModel);
|
||||||
|
|
||||||
window.setClientModel(&clientModel);
|
window.setClientModel(&clientModel);
|
||||||
window.setWalletModel(&walletModel);
|
window.addWallet("~Default", &walletModel);
|
||||||
|
window.setCurrentWallet("~Default");
|
||||||
|
|
||||||
// If -min option passed, start window minimized.
|
// If -min option passed, start window minimized.
|
||||||
if(GetBoolArg("-min"))
|
if(GetBoolArg("-min"))
|
||||||
|
@ -253,7 +254,7 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
window.hide();
|
window.hide();
|
||||||
window.setClientModel(0);
|
window.setClientModel(0);
|
||||||
window.setWalletModel(0);
|
window.removeAllWallets();
|
||||||
guiref = 0;
|
guiref = 0;
|
||||||
}
|
}
|
||||||
// Shutdown the core and its threads, but don't exit Bitcoin-Qt here
|
// Shutdown the core and its threads, but don't exit Bitcoin-Qt here
|
||||||
|
|
|
@ -10,26 +10,20 @@
|
||||||
#include "bitcoingui.h"
|
#include "bitcoingui.h"
|
||||||
|
|
||||||
#include "transactiontablemodel.h"
|
#include "transactiontablemodel.h"
|
||||||
#include "addressbookpage.h"
|
|
||||||
#include "sendcoinsdialog.h"
|
|
||||||
#include "signverifymessagedialog.h"
|
|
||||||
#include "optionsdialog.h"
|
#include "optionsdialog.h"
|
||||||
#include "aboutdialog.h"
|
#include "aboutdialog.h"
|
||||||
#include "clientmodel.h"
|
#include "clientmodel.h"
|
||||||
#include "walletmodel.h"
|
#include "walletmodel.h"
|
||||||
#include "editaddressdialog.h"
|
#include "walletframe.h"
|
||||||
#include "optionsmodel.h"
|
#include "optionsmodel.h"
|
||||||
#include "transactiondescdialog.h"
|
#include "transactiondescdialog.h"
|
||||||
#include "addresstablemodel.h"
|
|
||||||
#include "transactionview.h"
|
|
||||||
#include "overviewpage.h"
|
|
||||||
#include "bitcoinunits.h"
|
#include "bitcoinunits.h"
|
||||||
#include "guiconstants.h"
|
#include "guiconstants.h"
|
||||||
#include "askpassphrasedialog.h"
|
|
||||||
#include "notificator.h"
|
#include "notificator.h"
|
||||||
#include "guiutil.h"
|
#include "guiutil.h"
|
||||||
#include "rpcconsole.h"
|
#include "rpcconsole.h"
|
||||||
#include "ui_interface.h"
|
#include "ui_interface.h"
|
||||||
|
#include "wallet.h"
|
||||||
|
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
#include "macdockiconhandler.h"
|
#include "macdockiconhandler.h"
|
||||||
|
@ -56,13 +50,15 @@
|
||||||
#include <QStyle>
|
#include <QStyle>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <QDesktopWidget>
|
#include <QDesktopWidget>
|
||||||
|
#include <QListWidget>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
const QString BitcoinGUI::DEFAULT_WALLET = "~Default";
|
||||||
|
|
||||||
BitcoinGUI::BitcoinGUI(QWidget *parent):
|
BitcoinGUI::BitcoinGUI(QWidget *parent):
|
||||||
QMainWindow(parent),
|
QMainWindow(parent),
|
||||||
clientModel(0),
|
clientModel(0),
|
||||||
walletModel(0),
|
|
||||||
encryptWalletAction(0),
|
encryptWalletAction(0),
|
||||||
changePassphraseAction(0),
|
changePassphraseAction(0),
|
||||||
aboutQtAction(0),
|
aboutQtAction(0),
|
||||||
|
@ -95,31 +91,10 @@ BitcoinGUI::BitcoinGUI(QWidget *parent):
|
||||||
// Create system tray icon and notification
|
// Create system tray icon and notification
|
||||||
createTrayIcon();
|
createTrayIcon();
|
||||||
|
|
||||||
// Create tabs
|
// Create wallet frame and make it the central widget
|
||||||
overviewPage = new OverviewPage();
|
walletFrame = new WalletFrame(this);
|
||||||
|
setCentralWidget(walletFrame);
|
||||||
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 status bar
|
// Create status bar
|
||||||
statusBar();
|
statusBar();
|
||||||
|
|
||||||
|
@ -164,27 +139,11 @@ BitcoinGUI::BitcoinGUI(QWidget *parent):
|
||||||
|
|
||||||
syncIconMovie = new QMovie(":/movies/update_spinner", "mng", this);
|
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);
|
rpcConsole = new RPCConsole(this);
|
||||||
connect(openRPCConsoleAction, SIGNAL(triggered()), rpcConsole, SLOT(show()));
|
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)
|
// Install event filter to be able to catch status tip events (QEvent::StatusTip)
|
||||||
this->installEventFilter(this);
|
this->installEventFilter(this);
|
||||||
|
|
||||||
gotoOverviewPage();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BitcoinGUI::~BitcoinGUI()
|
BitcoinGUI::~BitcoinGUI()
|
||||||
|
@ -246,7 +205,7 @@ void BitcoinGUI::createActions()
|
||||||
connect(historyAction, SIGNAL(triggered()), this, SLOT(gotoHistoryPage()));
|
connect(historyAction, SIGNAL(triggered()), this, SLOT(gotoHistoryPage()));
|
||||||
connect(addressBookAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
|
connect(addressBookAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
|
||||||
connect(addressBookAction, SIGNAL(triggered()), this, SLOT(gotoAddressBookPage()));
|
connect(addressBookAction, SIGNAL(triggered()), this, SLOT(gotoAddressBookPage()));
|
||||||
|
|
||||||
quitAction = new QAction(QIcon(":/icons/quit"), tr("E&xit"), this);
|
quitAction = new QAction(QIcon(":/icons/quit"), tr("E&xit"), this);
|
||||||
quitAction->setStatusTip(tr("Quit application"));
|
quitAction->setStatusTip(tr("Quit application"));
|
||||||
quitAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q));
|
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
|
// Receive and report messages from network/worker thread
|
||||||
connect(clientModel, SIGNAL(message(QString,QString,unsigned int)), this, SLOT(message(QString,QString,unsigned int)));
|
connect(clientModel, SIGNAL(message(QString,QString,unsigned int)), this, SLOT(message(QString,QString,unsigned int)));
|
||||||
|
|
||||||
overviewPage->setClientModel(clientModel);
|
walletFrame->setClientModel(clientModel);
|
||||||
rpcConsole->setClientModel(clientModel);
|
|
||||||
addressBookPage->setOptionsModel(clientModel->getOptionsModel());
|
|
||||||
receiveCoinsPage->setOptionsModel(clientModel->getOptionsModel());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BitcoinGUI::setWalletModel(WalletModel *walletModel)
|
bool BitcoinGUI::addWallet(const QString& name, WalletModel *walletModel)
|
||||||
{
|
{
|
||||||
this->walletModel = walletModel;
|
return walletFrame->addWallet(name, 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)));
|
|
||||||
|
|
||||||
// Put transaction list in tabs
|
bool BitcoinGUI::setCurrentWallet(const QString& name)
|
||||||
transactionView->setModel(walletModel);
|
{
|
||||||
overviewPage->setWalletModel(walletModel);
|
return walletFrame->setCurrentWallet(name);
|
||||||
addressBookPage->setModel(walletModel->getAddressTableModel());
|
}
|
||||||
receiveCoinsPage->setModel(walletModel->getAddressTableModel());
|
|
||||||
sendCoinsPage->setModel(walletModel);
|
|
||||||
signVerifyMessageDialog->setModel(walletModel);
|
|
||||||
|
|
||||||
setEncryptionStatus(walletModel->getEncryptionStatus());
|
void BitcoinGUI::removeAllWallets()
|
||||||
connect(walletModel, SIGNAL(encryptionStatusChanged(int)), this, SLOT(setEncryptionStatus(int)));
|
{
|
||||||
|
walletFrame->removeAllWallets();
|
||||||
// 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::createTrayIcon()
|
void BitcoinGUI::createTrayIcon()
|
||||||
|
@ -509,6 +452,41 @@ void BitcoinGUI::aboutClicked()
|
||||||
dlg.exec();
|
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)
|
void BitcoinGUI::setNumConnections(int count)
|
||||||
{
|
{
|
||||||
QString icon;
|
QString icon;
|
||||||
|
@ -573,7 +551,7 @@ void BitcoinGUI::setNumBlocks(int count, int nTotalBlocks)
|
||||||
tooltip = tr("Up to date") + QString(".<br>") + tooltip;
|
tooltip = tr("Up to date") + QString(".<br>") + tooltip;
|
||||||
labelBlocksIcon->setPixmap(QIcon(":/icons/synced").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
|
labelBlocksIcon->setPixmap(QIcon(":/icons/synced").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
|
||||||
|
|
||||||
overviewPage->showOutOfSyncWarning(false);
|
walletFrame->showOutOfSyncWarning(false);
|
||||||
|
|
||||||
progressBarLabel->setVisible(false);
|
progressBarLabel->setVisible(false);
|
||||||
progressBar->setVisible(false);
|
progressBar->setVisible(false);
|
||||||
|
@ -608,7 +586,7 @@ void BitcoinGUI::setNumBlocks(int count, int nTotalBlocks)
|
||||||
syncIconMovie->jumpToNextFrame();
|
syncIconMovie->jumpToNextFrame();
|
||||||
prevBlocks = count;
|
prevBlocks = count;
|
||||||
|
|
||||||
overviewPage->showOutOfSyncWarning(true);
|
walletFrame->showOutOfSyncWarning(true);
|
||||||
|
|
||||||
tooltip += QString("<br>");
|
tooltip += QString("<br>");
|
||||||
tooltip += tr("Last received block was generated %1 ago.").arg(timeBehindText);
|
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);
|
*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
|
// On new transaction, make an info balloon
|
||||||
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
|
|
||||||
message((amount)<0 ? tr("Sent transaction") : tr("Incoming transaction"),
|
message((amount)<0 ? tr("Sent transaction") : tr("Incoming transaction"),
|
||||||
tr("Date: %1\n"
|
tr("Date: %1\n"
|
||||||
"Amount: %2\n"
|
"Amount: %2\n"
|
||||||
"Type: %3\n"
|
"Type: %3\n"
|
||||||
"Address: %4\n")
|
"Address: %4\n")
|
||||||
.arg(date)
|
.arg(date)
|
||||||
.arg(BitcoinUnits::formatWithUnit(walletModel->getOptionsModel()->getDisplayUnit(), amount, true))
|
.arg(BitcoinUnits::formatWithUnit(unit, amount, true))
|
||||||
.arg(type)
|
.arg(type)
|
||||||
.arg(address), CClientUIInterface::MSG_INFORMATION);
|
.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)
|
void BitcoinGUI::dragEnterEvent(QDragEnterEvent *event)
|
||||||
{
|
{
|
||||||
// Accept only URIs
|
// Accept only URIs
|
||||||
|
@ -830,13 +724,13 @@ void BitcoinGUI::dropEvent(QDropEvent *event)
|
||||||
QList<QUrl> uris = event->mimeData()->urls();
|
QList<QUrl> uris = event->mimeData()->urls();
|
||||||
foreach(const QUrl &uri, uris)
|
foreach(const QUrl &uri, uris)
|
||||||
{
|
{
|
||||||
if (sendCoinsPage->handleURI(uri.toString()))
|
if (walletFrame->handleURI(uri.toString()))
|
||||||
nValidUrisFound++;
|
nValidUrisFound++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if valid URIs were found
|
// if valid URIs were found
|
||||||
if (nValidUrisFound)
|
if (nValidUrisFound)
|
||||||
gotoSendCoinsPage();
|
walletFrame->gotoSendCoinsPage();
|
||||||
else
|
else
|
||||||
message(tr("URI handling"), tr("URI can not be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters."),
|
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);
|
CClientUIInterface::ICON_WARNING);
|
||||||
|
@ -860,12 +754,7 @@ bool BitcoinGUI::eventFilter(QObject *object, QEvent *event)
|
||||||
void BitcoinGUI::handleURI(QString strURI)
|
void BitcoinGUI::handleURI(QString strURI)
|
||||||
{
|
{
|
||||||
// URI has to be valid
|
// URI has to be valid
|
||||||
if (sendCoinsPage->handleURI(strURI))
|
if (!walletFrame->handleURI(strURI))
|
||||||
{
|
|
||||||
showNormalIfMinimized();
|
|
||||||
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."),
|
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);
|
CClientUIInterface::ICON_WARNING);
|
||||||
}
|
}
|
||||||
|
@ -901,49 +790,22 @@ void BitcoinGUI::setEncryptionStatus(int status)
|
||||||
|
|
||||||
void BitcoinGUI::encryptWallet(bool status)
|
void BitcoinGUI::encryptWallet(bool status)
|
||||||
{
|
{
|
||||||
if(!walletModel)
|
walletFrame->encryptWallet(status);
|
||||||
return;
|
|
||||||
AskPassphraseDialog dlg(status ? AskPassphraseDialog::Encrypt:
|
|
||||||
AskPassphraseDialog::Decrypt, this);
|
|
||||||
dlg.setModel(walletModel);
|
|
||||||
dlg.exec();
|
|
||||||
|
|
||||||
setEncryptionStatus(walletModel->getEncryptionStatus());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BitcoinGUI::backupWallet()
|
void BitcoinGUI::backupWallet()
|
||||||
{
|
{
|
||||||
QString saveDir = QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation);
|
walletFrame->backupWallet();
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BitcoinGUI::changePassphrase()
|
void BitcoinGUI::changePassphrase()
|
||||||
{
|
{
|
||||||
AskPassphraseDialog dlg(AskPassphraseDialog::ChangePass, this);
|
walletFrame->changePassphrase();
|
||||||
dlg.setModel(walletModel);
|
|
||||||
dlg.exec();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BitcoinGUI::unlockWallet()
|
void BitcoinGUI::unlockWallet()
|
||||||
{
|
{
|
||||||
if(!walletModel)
|
walletFrame->unlockWallet();
|
||||||
return;
|
|
||||||
// Unlock wallet when requested by wallet model
|
|
||||||
if(walletModel->getEncryptionStatus() == WalletModel::Locked)
|
|
||||||
{
|
|
||||||
AskPassphraseDialog dlg(AskPassphraseDialog::Unlock, this);
|
|
||||||
dlg.setModel(walletModel);
|
|
||||||
dlg.exec();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BitcoinGUI::showNormalIfMinimized(bool fToggleHidden)
|
void BitcoinGUI::showNormalIfMinimized(bool fToggleHidden)
|
||||||
|
|
|
@ -3,10 +3,14 @@
|
||||||
|
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
#include <QSystemTrayIcon>
|
#include <QSystemTrayIcon>
|
||||||
|
#include <QMap>
|
||||||
|
|
||||||
class TransactionTableModel;
|
class TransactionTableModel;
|
||||||
|
class WalletFrame;
|
||||||
|
class WalletView;
|
||||||
class ClientModel;
|
class ClientModel;
|
||||||
class WalletModel;
|
class WalletModel;
|
||||||
|
class WalletStack;
|
||||||
class TransactionView;
|
class TransactionView;
|
||||||
class OverviewPage;
|
class OverviewPage;
|
||||||
class AddressBookPage;
|
class AddressBookPage;
|
||||||
|
@ -15,11 +19,16 @@ class SignVerifyMessageDialog;
|
||||||
class Notificator;
|
class Notificator;
|
||||||
class RPCConsole;
|
class RPCConsole;
|
||||||
|
|
||||||
|
class CWallet;
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
class QLabel;
|
class QLabel;
|
||||||
class QModelIndex;
|
class QModelIndex;
|
||||||
class QProgressBar;
|
class QProgressBar;
|
||||||
class QStackedWidget;
|
class QStackedWidget;
|
||||||
|
class QUrl;
|
||||||
|
class QListWidget;
|
||||||
|
class QPushButton;
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -31,6 +40,8 @@ class BitcoinGUI : public QMainWindow
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
static const QString DEFAULT_WALLET;
|
||||||
|
|
||||||
explicit BitcoinGUI(QWidget *parent = 0);
|
explicit BitcoinGUI(QWidget *parent = 0);
|
||||||
~BitcoinGUI();
|
~BitcoinGUI();
|
||||||
|
|
||||||
|
@ -42,7 +53,11 @@ public:
|
||||||
The wallet model represents a bitcoin wallet, and offers access to the list of transactions, address book and sending
|
The wallet model represents a bitcoin wallet, and offers access to the list of transactions, address book and sending
|
||||||
functionality.
|
functionality.
|
||||||
*/
|
*/
|
||||||
void setWalletModel(WalletModel *walletModel);
|
|
||||||
|
bool addWallet(const QString& name, WalletModel *walletModel);
|
||||||
|
bool setCurrentWallet(const QString& name);
|
||||||
|
|
||||||
|
void removeAllWallets();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void changeEvent(QEvent *e);
|
void changeEvent(QEvent *e);
|
||||||
|
@ -53,16 +68,7 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ClientModel *clientModel;
|
ClientModel *clientModel;
|
||||||
WalletModel *walletModel;
|
WalletFrame *walletFrame;
|
||||||
|
|
||||||
QStackedWidget *centralWidget;
|
|
||||||
|
|
||||||
OverviewPage *overviewPage;
|
|
||||||
QWidget *transactionsPage;
|
|
||||||
AddressBookPage *addressBookPage;
|
|
||||||
AddressBookPage *receiveCoinsPage;
|
|
||||||
SendCoinsDialog *sendCoinsPage;
|
|
||||||
SignVerifyMessageDialog *signVerifyMessageDialog;
|
|
||||||
|
|
||||||
QLabel *labelEncryptionIcon;
|
QLabel *labelEncryptionIcon;
|
||||||
QLabel *labelConnectionsIcon;
|
QLabel *labelConnectionsIcon;
|
||||||
|
@ -88,7 +94,7 @@ private:
|
||||||
QAction *changePassphraseAction;
|
QAction *changePassphraseAction;
|
||||||
QAction *aboutQtAction;
|
QAction *aboutQtAction;
|
||||||
QAction *openRPCConsoleAction;
|
QAction *openRPCConsoleAction;
|
||||||
|
|
||||||
QSystemTrayIcon *trayIcon;
|
QSystemTrayIcon *trayIcon;
|
||||||
Notificator *notificator;
|
Notificator *notificator;
|
||||||
TransactionView *transactionView;
|
TransactionView *transactionView;
|
||||||
|
@ -143,6 +149,9 @@ public slots:
|
||||||
void askFee(qint64 nFeeRequired, bool *payFee);
|
void askFee(qint64 nFeeRequired, bool *payFee);
|
||||||
void handleURI(QString strURI);
|
void handleURI(QString strURI);
|
||||||
|
|
||||||
|
/** Show incoming transaction notification for new transactions. */
|
||||||
|
void incomingTransaction(const QString& date, int unit, qint64 amount, const QString& type, const QString& address);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
/** Switch to overview (home) page */
|
/** Switch to overview (home) page */
|
||||||
void gotoOverviewPage();
|
void gotoOverviewPage();
|
||||||
|
@ -153,7 +162,7 @@ private slots:
|
||||||
/** Switch to receive coins page */
|
/** Switch to receive coins page */
|
||||||
void gotoReceiveCoinsPage();
|
void gotoReceiveCoinsPage();
|
||||||
/** Switch to send coins page */
|
/** Switch to send coins page */
|
||||||
void gotoSendCoinsPage(QString addr = "");
|
void gotoSendCoinsPage();
|
||||||
|
|
||||||
/** Show Sign/Verify Message dialog and switch to sign message tab */
|
/** Show Sign/Verify Message dialog and switch to sign message tab */
|
||||||
void gotoSignMessageTab(QString addr = "");
|
void gotoSignMessageTab(QString addr = "");
|
||||||
|
@ -168,11 +177,6 @@ private slots:
|
||||||
/** Handle tray icon clicked */
|
/** Handle tray icon clicked */
|
||||||
void trayIconActivated(QSystemTrayIcon::ActivationReason reason);
|
void trayIconActivated(QSystemTrayIcon::ActivationReason reason);
|
||||||
#endif
|
#endif
|
||||||
/** Show incoming transaction notification for new transactions.
|
|
||||||
|
|
||||||
The new items are those between start and end inclusive, under the given parent item.
|
|
||||||
*/
|
|
||||||
void incomingTransaction(const QModelIndex& parent, int start, int /*end*/);
|
|
||||||
/** Encrypt the wallet */
|
/** Encrypt the wallet */
|
||||||
void encryptWallet(bool status);
|
void encryptWallet(bool status);
|
||||||
/** Backup the wallet */
|
/** Backup the wallet */
|
||||||
|
|
129
src/qt/walletframe.cpp
Normal file
129
src/qt/walletframe.cpp
Normal file
|
@ -0,0 +1,129 @@
|
||||||
|
/*
|
||||||
|
* Qt4 bitcoin GUI.
|
||||||
|
*
|
||||||
|
* W.J. van der Laan 2011-2012
|
||||||
|
* The Bitcoin Developers 2011-2013
|
||||||
|
*/
|
||||||
|
#include "walletframe.h"
|
||||||
|
#include "bitcoingui.h"
|
||||||
|
#include "walletstack.h"
|
||||||
|
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QMessageBox>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
WalletFrame::WalletFrame(BitcoinGUI *_gui) :
|
||||||
|
QFrame(_gui),
|
||||||
|
gui(_gui),
|
||||||
|
clientModel(0)
|
||||||
|
{
|
||||||
|
// Leave HBox hook for adding a list view later
|
||||||
|
QHBoxLayout *walletFrameLayout = new QHBoxLayout(this);
|
||||||
|
walletStack = new WalletStack(this);
|
||||||
|
walletStack->setBitcoinGUI(gui);
|
||||||
|
walletFrameLayout->addWidget(walletStack);
|
||||||
|
}
|
||||||
|
|
||||||
|
WalletFrame::~WalletFrame()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletFrame::setClientModel(ClientModel *clientModel)
|
||||||
|
{
|
||||||
|
this->clientModel = clientModel;
|
||||||
|
walletStack->setClientModel(clientModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WalletFrame::addWallet(const QString& name, WalletModel *walletModel)
|
||||||
|
{
|
||||||
|
return walletStack->addWallet(name, walletModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WalletFrame::setCurrentWallet(const QString& name)
|
||||||
|
{
|
||||||
|
// TODO: Check if valid name
|
||||||
|
walletStack->setCurrentWallet(name);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletFrame::removeAllWallets()
|
||||||
|
{
|
||||||
|
walletStack->removeAllWallets();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WalletFrame::handleURI(const QString &uri)
|
||||||
|
{
|
||||||
|
return walletStack->handleURI(uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletFrame::showOutOfSyncWarning(bool fShow)
|
||||||
|
{
|
||||||
|
if (!walletStack) {
|
||||||
|
QMessageBox box;
|
||||||
|
box.setText("walletStack is null");
|
||||||
|
box.exec();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
walletStack->showOutOfSyncWarning(fShow);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletFrame::gotoOverviewPage()
|
||||||
|
{
|
||||||
|
walletStack->gotoOverviewPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletFrame::gotoHistoryPage()
|
||||||
|
{
|
||||||
|
walletStack->gotoHistoryPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletFrame::gotoAddressBookPage()
|
||||||
|
{
|
||||||
|
walletStack->gotoAddressBookPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletFrame::gotoReceiveCoinsPage()
|
||||||
|
{
|
||||||
|
walletStack->gotoReceiveCoinsPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletFrame::gotoSendCoinsPage()
|
||||||
|
{
|
||||||
|
walletStack->gotoSendCoinsPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletFrame::gotoSignMessageTab(QString addr)
|
||||||
|
{
|
||||||
|
walletStack->gotoSignMessageTab(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletFrame::gotoVerifyMessageTab(QString addr)
|
||||||
|
{
|
||||||
|
walletStack->gotoSignMessageTab(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletFrame::encryptWallet(bool status)
|
||||||
|
{
|
||||||
|
walletStack->encryptWallet(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletFrame::backupWallet()
|
||||||
|
{
|
||||||
|
walletStack->backupWallet();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletFrame::changePassphrase()
|
||||||
|
{
|
||||||
|
walletStack->changePassphrase();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletFrame::unlockWallet()
|
||||||
|
{
|
||||||
|
walletStack->unlockWallet();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletFrame::setEncryptionStatus()
|
||||||
|
{
|
||||||
|
walletStack->setEncryptionStatus();
|
||||||
|
}
|
73
src/qt/walletframe.h
Normal file
73
src/qt/walletframe.h
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
/*
|
||||||
|
* Qt4 bitcoin GUI.
|
||||||
|
*
|
||||||
|
* W.J. van der Laan 2011-2012
|
||||||
|
* The Bitcoin Developers 2011-2013
|
||||||
|
*/
|
||||||
|
#ifndef WALLETFRAME_H
|
||||||
|
#define WALLETFRAME_H
|
||||||
|
|
||||||
|
#include <QFrame>
|
||||||
|
|
||||||
|
class BitcoinGUI;
|
||||||
|
class ClientModel;
|
||||||
|
class WalletModel;
|
||||||
|
class WalletStack;
|
||||||
|
|
||||||
|
class WalletFrame : public QFrame
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit WalletFrame(BitcoinGUI *_gui);
|
||||||
|
~WalletFrame();
|
||||||
|
|
||||||
|
void setClientModel(ClientModel *clientModel);
|
||||||
|
|
||||||
|
bool addWallet(const QString& name, WalletModel *walletModel);
|
||||||
|
bool setCurrentWallet(const QString& name);
|
||||||
|
|
||||||
|
void removeAllWallets();
|
||||||
|
|
||||||
|
bool handleURI(const QString &uri);
|
||||||
|
|
||||||
|
void showOutOfSyncWarning(bool fShow);
|
||||||
|
|
||||||
|
private:
|
||||||
|
BitcoinGUI *gui;
|
||||||
|
ClientModel *clientModel;
|
||||||
|
WalletStack *walletStack;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
/** Switch to overview (home) page */
|
||||||
|
void gotoOverviewPage();
|
||||||
|
/** Switch to history (transactions) page */
|
||||||
|
void gotoHistoryPage();
|
||||||
|
/** Switch to address book page */
|
||||||
|
void gotoAddressBookPage();
|
||||||
|
/** Switch to receive coins page */
|
||||||
|
void gotoReceiveCoinsPage();
|
||||||
|
/** Switch to send coins page */
|
||||||
|
void gotoSendCoinsPage();
|
||||||
|
|
||||||
|
/** Show Sign/Verify Message dialog and switch to sign message tab */
|
||||||
|
void gotoSignMessageTab(QString addr = "");
|
||||||
|
/** Show Sign/Verify Message dialog and switch to verify message tab */
|
||||||
|
void gotoVerifyMessageTab(QString addr = "");
|
||||||
|
|
||||||
|
/** Encrypt the wallet */
|
||||||
|
void encryptWallet(bool status);
|
||||||
|
/** Backup the wallet */
|
||||||
|
void backupWallet();
|
||||||
|
/** Change encrypted wallet passphrase */
|
||||||
|
void changePassphrase();
|
||||||
|
/** Ask for passphrase to unlock wallet temporarily */
|
||||||
|
void unlockWallet();
|
||||||
|
|
||||||
|
/** Set the encryption status as shown in the UI.
|
||||||
|
@param[in] status current encryption status
|
||||||
|
@see WalletModel::EncryptionStatus
|
||||||
|
*/
|
||||||
|
void setEncryptionStatus();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // WALLETFRAME_H
|
155
src/qt/walletstack.cpp
Normal file
155
src/qt/walletstack.cpp
Normal file
|
@ -0,0 +1,155 @@
|
||||||
|
/*
|
||||||
|
* Qt4 bitcoin GUI.
|
||||||
|
*
|
||||||
|
* W.J. van der Laan 2011-2012
|
||||||
|
* The Bitcoin Developers 2011-2013
|
||||||
|
*/
|
||||||
|
#include "walletstack.h"
|
||||||
|
#include "walletview.h"
|
||||||
|
#include "bitcoingui.h"
|
||||||
|
|
||||||
|
#include <QMap>
|
||||||
|
#include <QMessageBox>
|
||||||
|
|
||||||
|
WalletStack::WalletStack(QWidget *parent) :
|
||||||
|
QStackedWidget(parent),
|
||||||
|
clientModel(0),
|
||||||
|
bOutOfSync(true)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
WalletStack::~WalletStack()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WalletStack::addWallet(const QString& name, WalletModel *walletModel)
|
||||||
|
{
|
||||||
|
if (!gui || !clientModel || mapWalletViews.count(name) > 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
WalletView *walletView = new WalletView(this, gui);
|
||||||
|
walletView->setBitcoinGUI(gui);
|
||||||
|
walletView->setClientModel(clientModel);
|
||||||
|
walletView->setWalletModel(walletModel);
|
||||||
|
walletView->showOutOfSyncWarning(bOutOfSync);
|
||||||
|
addWidget(walletView);
|
||||||
|
mapWalletViews[name] = walletView;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WalletStack::removeWallet(const QString& name)
|
||||||
|
{
|
||||||
|
if (mapWalletViews.count(name) == 0) return false;
|
||||||
|
WalletView *walletView = mapWalletViews.take(name);
|
||||||
|
removeWidget(walletView);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletStack::removeAllWallets()
|
||||||
|
{
|
||||||
|
QMap<QString, WalletView*>::const_iterator i;
|
||||||
|
for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
|
||||||
|
removeWidget(i.value());
|
||||||
|
mapWalletViews.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WalletStack::handleURI(const QString &uri)
|
||||||
|
{
|
||||||
|
WalletView *walletView = (WalletView*)currentWidget();
|
||||||
|
if (!walletView) return false;
|
||||||
|
|
||||||
|
return walletView->handleURI(uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletStack::showOutOfSyncWarning(bool fShow)
|
||||||
|
{
|
||||||
|
bOutOfSync = fShow;
|
||||||
|
QMap<QString, WalletView*>::const_iterator i;
|
||||||
|
for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
|
||||||
|
i.value()->showOutOfSyncWarning(fShow);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletStack::gotoOverviewPage()
|
||||||
|
{
|
||||||
|
QMap<QString, WalletView*>::const_iterator i;
|
||||||
|
for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
|
||||||
|
i.value()->gotoOverviewPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletStack::gotoHistoryPage()
|
||||||
|
{
|
||||||
|
QMap<QString, WalletView*>::const_iterator i;
|
||||||
|
for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
|
||||||
|
i.value()->gotoHistoryPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletStack::gotoAddressBookPage()
|
||||||
|
{
|
||||||
|
QMap<QString, WalletView*>::const_iterator i;
|
||||||
|
for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
|
||||||
|
i.value()->gotoAddressBookPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletStack::gotoReceiveCoinsPage()
|
||||||
|
{
|
||||||
|
QMap<QString, WalletView*>::const_iterator i;
|
||||||
|
for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
|
||||||
|
i.value()->gotoReceiveCoinsPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletStack::gotoSendCoinsPage()
|
||||||
|
{
|
||||||
|
QMap<QString, WalletView*>::const_iterator i;
|
||||||
|
for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
|
||||||
|
i.value()->gotoSendCoinsPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletStack::gotoSignMessageTab(QString addr)
|
||||||
|
{
|
||||||
|
WalletView *walletView = (WalletView*)currentWidget();
|
||||||
|
if (walletView) walletView->gotoSignMessageTab(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletStack::gotoVerifyMessageTab(QString addr)
|
||||||
|
{
|
||||||
|
WalletView *walletView = (WalletView*)currentWidget();
|
||||||
|
if (walletView) walletView->gotoVerifyMessageTab(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletStack::encryptWallet(bool status)
|
||||||
|
{
|
||||||
|
WalletView *walletView = (WalletView*)currentWidget();
|
||||||
|
if (walletView) walletView->encryptWallet(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletStack::backupWallet()
|
||||||
|
{
|
||||||
|
WalletView *walletView = (WalletView*)currentWidget();
|
||||||
|
if (walletView) walletView->backupWallet();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletStack::changePassphrase()
|
||||||
|
{
|
||||||
|
WalletView *walletView = (WalletView*)currentWidget();
|
||||||
|
if (walletView) walletView->changePassphrase();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletStack::unlockWallet()
|
||||||
|
{
|
||||||
|
WalletView *walletView = (WalletView*)currentWidget();
|
||||||
|
if (walletView) walletView->unlockWallet();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletStack::setEncryptionStatus()
|
||||||
|
{
|
||||||
|
WalletView *walletView = (WalletView*)currentWidget();
|
||||||
|
if (walletView) walletView->setEncryptionStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WalletStack::setCurrentWallet(const QString& name)
|
||||||
|
{
|
||||||
|
if (mapWalletViews.count(name) == 0) return;
|
||||||
|
WalletView *walletView = mapWalletViews.value(name);
|
||||||
|
setCurrentWidget(walletView);
|
||||||
|
walletView->setEncryptionStatus();
|
||||||
|
}
|
102
src/qt/walletstack.h
Normal file
102
src/qt/walletstack.h
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
/*
|
||||||
|
* Qt4 bitcoin GUI.
|
||||||
|
*
|
||||||
|
* W.J. van der Laan 2011-2012
|
||||||
|
* The Bitcoin Developers 2011-2013
|
||||||
|
*/
|
||||||
|
#ifndef WALLETSTACK_H
|
||||||
|
#define WALLETSTACK_H
|
||||||
|
|
||||||
|
#include <QStackedWidget>
|
||||||
|
#include <QMap>
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
|
class BitcoinGUI;
|
||||||
|
class TransactionTableModel;
|
||||||
|
class ClientModel;
|
||||||
|
class WalletModel;
|
||||||
|
class WalletView;
|
||||||
|
class TransactionView;
|
||||||
|
class OverviewPage;
|
||||||
|
class AddressBookPage;
|
||||||
|
class SendCoinsDialog;
|
||||||
|
class SignVerifyMessageDialog;
|
||||||
|
class Notificator;
|
||||||
|
class RPCConsole;
|
||||||
|
|
||||||
|
class CWalletManager;
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
class QLabel;
|
||||||
|
class QModelIndex;
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
/*
|
||||||
|
WalletStack class. This class is a container for WalletView instances. It takes the place of centralWidget.
|
||||||
|
It was added to support multiple wallet functionality. It communicates with both the client and the
|
||||||
|
wallet models to give the user an up-to-date view of the current core state. It manages all the wallet views
|
||||||
|
it contains and updates them accordingly.
|
||||||
|
*/
|
||||||
|
class WalletStack : public QStackedWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit WalletStack(QWidget *parent = 0);
|
||||||
|
~WalletStack();
|
||||||
|
|
||||||
|
void setBitcoinGUI(BitcoinGUI *gui) { this->gui = gui; }
|
||||||
|
|
||||||
|
void setClientModel(ClientModel *clientModel) { this->clientModel = clientModel; }
|
||||||
|
|
||||||
|
bool addWallet(const QString& name, WalletModel *walletModel);
|
||||||
|
bool removeWallet(const QString& name);
|
||||||
|
|
||||||
|
void removeAllWallets();
|
||||||
|
|
||||||
|
bool handleURI(const QString &uri);
|
||||||
|
|
||||||
|
void showOutOfSyncWarning(bool fShow);
|
||||||
|
|
||||||
|
private:
|
||||||
|
BitcoinGUI *gui;
|
||||||
|
ClientModel *clientModel;
|
||||||
|
QMap<QString, WalletView*> mapWalletViews;
|
||||||
|
|
||||||
|
bool bOutOfSync;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void setCurrentWallet(const QString& name);
|
||||||
|
|
||||||
|
/** Switch to overview (home) page */
|
||||||
|
void gotoOverviewPage();
|
||||||
|
/** Switch to history (transactions) page */
|
||||||
|
void gotoHistoryPage();
|
||||||
|
/** Switch to address book page */
|
||||||
|
void gotoAddressBookPage();
|
||||||
|
/** Switch to receive coins page */
|
||||||
|
void gotoReceiveCoinsPage();
|
||||||
|
/** Switch to send coins page */
|
||||||
|
void gotoSendCoinsPage();
|
||||||
|
|
||||||
|
/** Show Sign/Verify Message dialog and switch to sign message tab */
|
||||||
|
void gotoSignMessageTab(QString addr = "");
|
||||||
|
/** Show Sign/Verify Message dialog and switch to verify message tab */
|
||||||
|
void gotoVerifyMessageTab(QString addr = "");
|
||||||
|
|
||||||
|
/** Encrypt the wallet */
|
||||||
|
void encryptWallet(bool status);
|
||||||
|
/** Backup the wallet */
|
||||||
|
void backupWallet();
|
||||||
|
/** Change encrypted wallet passphrase */
|
||||||
|
void changePassphrase();
|
||||||
|
/** Ask for passphrase to unlock wallet temporarily */
|
||||||
|
void unlockWallet();
|
||||||
|
|
||||||
|
/** Set the encryption status as shown in the UI.
|
||||||
|
@param[in] status current encryption status
|
||||||
|
@see WalletModel::EncryptionStatus
|
||||||
|
*/
|
||||||
|
void setEncryptionStatus();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // WALLETSTACK_H
|
354
src/qt/walletview.cpp
Normal file
354
src/qt/walletview.cpp
Normal file
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
132
src/qt/walletview.h
Normal file
132
src/qt/walletview.h
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
/*
|
||||||
|
* Qt4 bitcoin GUI.
|
||||||
|
*
|
||||||
|
* W.J. van der Laan 2011-2012
|
||||||
|
* The Bitcoin Developers 2011-2013
|
||||||
|
*/
|
||||||
|
#ifndef WALLETVIEW_H
|
||||||
|
#define WALLETVIEW_H
|
||||||
|
|
||||||
|
#include <QStackedWidget>
|
||||||
|
|
||||||
|
class BitcoinGUI;
|
||||||
|
class TransactionTableModel;
|
||||||
|
class ClientModel;
|
||||||
|
class WalletModel;
|
||||||
|
class TransactionView;
|
||||||
|
class OverviewPage;
|
||||||
|
class AddressBookPage;
|
||||||
|
class SendCoinsDialog;
|
||||||
|
class SignVerifyMessageDialog;
|
||||||
|
class Notificator;
|
||||||
|
class RPCConsole;
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
class QLabel;
|
||||||
|
class QModelIndex;
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
/*
|
||||||
|
WalletView class. This class represents the view to a single wallet.
|
||||||
|
It was added to support multiple wallet functionality. Each wallet gets its own WalletView instance.
|
||||||
|
It communicates with both the client and the wallet models to give the user an up-to-date view of the
|
||||||
|
current core state.
|
||||||
|
*/
|
||||||
|
class WalletView : public QStackedWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit WalletView(QWidget *parent, BitcoinGUI *_gui);
|
||||||
|
~WalletView();
|
||||||
|
|
||||||
|
void setBitcoinGUI(BitcoinGUI *gui);
|
||||||
|
/** Set the client model.
|
||||||
|
The client model represents the part of the core that communicates with the P2P network, and is wallet-agnostic.
|
||||||
|
*/
|
||||||
|
void setClientModel(ClientModel *clientModel);
|
||||||
|
/** Set the wallet model.
|
||||||
|
The wallet model represents a bitcoin wallet, and offers access to the list of transactions, address book and sending
|
||||||
|
functionality.
|
||||||
|
*/
|
||||||
|
void setWalletModel(WalletModel *walletModel);
|
||||||
|
|
||||||
|
bool handleURI(const QString &uri);
|
||||||
|
|
||||||
|
void showOutOfSyncWarning(bool fShow);
|
||||||
|
|
||||||
|
private:
|
||||||
|
BitcoinGUI *gui;
|
||||||
|
ClientModel *clientModel;
|
||||||
|
WalletModel *walletModel;
|
||||||
|
|
||||||
|
OverviewPage *overviewPage;
|
||||||
|
QWidget *transactionsPage;
|
||||||
|
AddressBookPage *addressBookPage;
|
||||||
|
AddressBookPage *receiveCoinsPage;
|
||||||
|
SendCoinsDialog *sendCoinsPage;
|
||||||
|
SignVerifyMessageDialog *signVerifyMessageDialog;
|
||||||
|
|
||||||
|
QLabel *labelEncryptionIcon;
|
||||||
|
QLabel *labelConnectionsIcon;
|
||||||
|
QLabel *labelBlocksIcon;
|
||||||
|
QLabel *progressBarLabel;
|
||||||
|
|
||||||
|
QAction *overviewAction;
|
||||||
|
QAction *historyAction;
|
||||||
|
QAction *quitAction;
|
||||||
|
QAction *sendCoinsAction;
|
||||||
|
QAction *addressBookAction;
|
||||||
|
QAction *signMessageAction;
|
||||||
|
QAction *verifyMessageAction;
|
||||||
|
QAction *aboutAction;
|
||||||
|
QAction *receiveCoinsAction;
|
||||||
|
QAction *optionsAction;
|
||||||
|
QAction *toggleHideAction;
|
||||||
|
QAction *exportAction;
|
||||||
|
QAction *encryptWalletAction;
|
||||||
|
QAction *backupWalletAction;
|
||||||
|
QAction *changePassphraseAction;
|
||||||
|
QAction *aboutQtAction;
|
||||||
|
QAction *openRPCConsoleAction;
|
||||||
|
|
||||||
|
TransactionView *transactionView;
|
||||||
|
|
||||||
|
/** Create the main UI actions. */
|
||||||
|
void createActions();
|
||||||
|
/** Create the menu bar and sub-menus. */
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
/** Switch to overview (home) page */
|
||||||
|
void gotoOverviewPage();
|
||||||
|
/** Switch to history (transactions) page */
|
||||||
|
void gotoHistoryPage();
|
||||||
|
/** Switch to address book page */
|
||||||
|
void gotoAddressBookPage();
|
||||||
|
/** Switch to receive coins page */
|
||||||
|
void gotoReceiveCoinsPage();
|
||||||
|
/** Switch to send coins page */
|
||||||
|
void gotoSendCoinsPage();
|
||||||
|
|
||||||
|
/** Show Sign/Verify Message dialog and switch to sign message tab */
|
||||||
|
void gotoSignMessageTab(QString addr = "");
|
||||||
|
/** Show Sign/Verify Message dialog and switch to verify message tab */
|
||||||
|
void gotoVerifyMessageTab(QString addr = "");
|
||||||
|
|
||||||
|
/** Show incoming transaction notification for new transactions.
|
||||||
|
|
||||||
|
The new items are those between start and end inclusive, under the given parent item.
|
||||||
|
*/
|
||||||
|
void incomingTransaction(const QModelIndex& parent, int start, int /*end*/);
|
||||||
|
/** Encrypt the wallet */
|
||||||
|
void encryptWallet(bool status);
|
||||||
|
/** Backup the wallet */
|
||||||
|
void backupWallet();
|
||||||
|
/** Change encrypted wallet passphrase */
|
||||||
|
void changePassphrase();
|
||||||
|
/** Ask for passphrase to unlock wallet temporarily */
|
||||||
|
void unlockWallet();
|
||||||
|
|
||||||
|
void setEncryptionStatus();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // WALLETVIEW_H
|
Loading…
Reference in a new issue