Browse Source
- This commit is a minimal restructuring necessary to support multiple wallets in the UI. Please see multiwallet-qt.txt for details.miguelfreitas
Eric Lombrozo
12 years ago
11 changed files with 1099 additions and 228 deletions
@ -0,0 +1,53 @@
@@ -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(); |
@ -0,0 +1,129 @@
@@ -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(); |
||||
} |
@ -0,0 +1,73 @@
@@ -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
|
@ -0,0 +1,155 @@
@@ -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(); |
||||
} |
@ -0,0 +1,102 @@
@@ -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
|
@ -0,0 +1,354 @@
@@ -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(); |
||||
} |
||||
} |
@ -0,0 +1,132 @@
@@ -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 new issue