aboutsummaryrefslogtreecommitdiff
path: root/src/qt
diff options
context:
space:
mode:
Diffstat (limited to 'src/qt')
-rw-r--r--src/qt/askpassphrasedialog.cpp2
-rw-r--r--src/qt/bitcoin.cpp5
-rw-r--r--src/qt/bitcoinamountfield.cpp5
-rw-r--r--src/qt/bitcoingui.cpp307
-rw-r--r--src/qt/bitcoingui.h40
-rw-r--r--src/qt/forms/overviewpage.ui18
-rw-r--r--src/qt/guiutil.cpp2
-rw-r--r--src/qt/overviewpage.cpp8
-rw-r--r--src/qt/overviewpage.h1
-rw-r--r--src/qt/transactionview.cpp8
-rw-r--r--src/qt/transactionview.h1
-rw-r--r--src/qt/walletframe.cpp129
-rw-r--r--src/qt/walletframe.h73
-rw-r--r--src/qt/walletmodel.cpp2
-rw-r--r--src/qt/walletstack.cpp155
-rw-r--r--src/qt/walletstack.h102
-rw-r--r--src/qt/walletview.cpp359
-rw-r--r--src/qt/walletview.h132
18 files changed, 1094 insertions, 255 deletions
diff --git a/src/qt/askpassphrasedialog.cpp b/src/qt/askpassphrasedialog.cpp
index cf35ee2457..f165c11cb1 100644
--- a/src/qt/askpassphrasedialog.cpp
+++ b/src/qt/askpassphrasedialog.cpp
@@ -235,7 +235,7 @@ bool AskPassphraseDialog::eventFilter(QObject *object, QEvent *event)
if (str.length() != 0) {
const QChar *psz = str.unicode();
bool fShift = (ke->modifiers() & Qt::ShiftModifier) != 0;
- if ((fShift && psz->isLower()) || (!fShift && psz->isUpper())) {
+ if ((fShift && *psz >= 'a' && *psz <= 'z') || (!fShift && *psz >= 'A' && *psz <= 'Z')) {
fCapsLock = true;
ui->capsLabel->setText(tr("Warning: The Caps Lock key is on!"));
} else if (psz->isLetter()) {
diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp
index e3d51be54a..346128c0c4 100644
--- a/src/qt/bitcoin.cpp
+++ b/src/qt/bitcoin.cpp
@@ -232,7 +232,8 @@ int main(int argc, char *argv[])
WalletModel walletModel(pwalletMain, &optionsModel);
window.setClientModel(&clientModel);
- window.setWalletModel(&walletModel);
+ window.addWallet("~Default", &walletModel);
+ window.setCurrentWallet("~Default");
// If -min option passed, start window minimized.
if(GetBoolArg("-min"))
@@ -253,7 +254,7 @@ int main(int argc, char *argv[])
window.hide();
window.setClientModel(0);
- window.setWalletModel(0);
+ window.removeAllWallets();
guiref = 0;
}
// Shutdown the core and its threads, but don't exit Bitcoin-Qt here
diff --git a/src/qt/bitcoinamountfield.cpp b/src/qt/bitcoinamountfield.cpp
index ddf185c415..4fa2ca508b 100644
--- a/src/qt/bitcoinamountfield.cpp
+++ b/src/qt/bitcoinamountfield.cpp
@@ -145,6 +145,11 @@ void BitcoinAmountField::unitChanged(int idx)
amount->setDecimals(BitcoinUnits::decimals(currentUnit));
amount->setMaximum(qPow(10, BitcoinUnits::amountDigits(currentUnit)) - qPow(10, -amount->decimals()));
+ if(currentUnit == BitcoinUnits::uBTC)
+ amount->setSingleStep(0.01);
+ else
+ amount->setSingleStep(0.001);
+
if(valid)
{
// If value was valid, re-place it in the widget with the new unit
diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
index 0d951718bb..e41ce96082 100644
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -10,26 +10,20 @@
#include "bitcoingui.h"
#include "transactiontablemodel.h"
-#include "addressbookpage.h"
-#include "sendcoinsdialog.h"
-#include "signverifymessagedialog.h"
#include "optionsdialog.h"
#include "aboutdialog.h"
#include "clientmodel.h"
#include "walletmodel.h"
-#include "editaddressdialog.h"
+#include "walletframe.h"
#include "optionsmodel.h"
#include "transactiondescdialog.h"
-#include "addresstablemodel.h"
-#include "transactionview.h"
-#include "overviewpage.h"
#include "bitcoinunits.h"
#include "guiconstants.h"
-#include "askpassphrasedialog.h"
#include "notificator.h"
#include "guiutil.h"
#include "rpcconsole.h"
#include "ui_interface.h"
+#include "wallet.h"
#ifdef Q_OS_MAC
#include "macdockiconhandler.h"
@@ -54,13 +48,17 @@
#include <QUrl>
#include <QMimeData>
#include <QStyle>
+#include <QSettings>
+#include <QDesktopWidget>
+#include <QListWidget>
#include <iostream>
+const QString BitcoinGUI::DEFAULT_WALLET = "~Default";
+
BitcoinGUI::BitcoinGUI(QWidget *parent):
QMainWindow(parent),
clientModel(0),
- walletModel(0),
encryptWalletAction(0),
changePassphraseAction(0),
aboutQtAction(0),
@@ -69,7 +67,7 @@ BitcoinGUI::BitcoinGUI(QWidget *parent):
rpcConsole(0),
prevBlocks(0)
{
- resize(850, 550);
+ restoreWindowGeometry();
setWindowTitle(tr("Bitcoin") + " - " + tr("Wallet"));
#ifndef Q_OS_MAC
qApp->setWindowIcon(QIcon(":icons/bitcoin"));
@@ -93,31 +91,10 @@ BitcoinGUI::BitcoinGUI(QWidget *parent):
// Create system tray icon and notification
createTrayIcon();
- // Create tabs
- overviewPage = new OverviewPage();
-
- transactionsPage = new QWidget(this);
- QVBoxLayout *vbox = new QVBoxLayout();
- transactionView = new TransactionView(this);
- vbox->addWidget(transactionView);
- transactionsPage->setLayout(vbox);
-
- addressBookPage = new AddressBookPage(AddressBookPage::ForEditing, AddressBookPage::SendingTab);
-
- receiveCoinsPage = new AddressBookPage(AddressBookPage::ForEditing, AddressBookPage::ReceivingTab);
-
- sendCoinsPage = new SendCoinsDialog(this);
-
- signVerifyMessageDialog = new SignVerifyMessageDialog(this);
-
- centralWidget = new QStackedWidget(this);
- centralWidget->addWidget(overviewPage);
- centralWidget->addWidget(transactionsPage);
- centralWidget->addWidget(addressBookPage);
- centralWidget->addWidget(receiveCoinsPage);
- centralWidget->addWidget(sendCoinsPage);
- setCentralWidget(centralWidget);
-
+ // Create wallet frame and make it the central widget
+ walletFrame = new WalletFrame(this);
+ setCentralWidget(walletFrame);
+
// Create status bar
statusBar();
@@ -162,31 +139,16 @@ BitcoinGUI::BitcoinGUI(QWidget *parent):
syncIconMovie = new QMovie(":/movies/update_spinner", "mng", this);
- // Clicking on a transaction on the overview page simply sends you to transaction history page
- connect(overviewPage, SIGNAL(transactionClicked(QModelIndex)), this, SLOT(gotoHistoryPage()));
- connect(overviewPage, SIGNAL(transactionClicked(QModelIndex)), transactionView, SLOT(focusTransaction(QModelIndex)));
-
- // Double-clicking on a transaction on the transaction history page shows details
- connect(transactionView, SIGNAL(doubleClicked(QModelIndex)), transactionView, SLOT(showDetails()));
-
rpcConsole = new RPCConsole(this);
connect(openRPCConsoleAction, SIGNAL(triggered()), rpcConsole, SLOT(show()));
- // Clicking on "Send Coins" in the address book sends you to the send coins tab
- connect(addressBookPage, SIGNAL(sendCoins(QString)), this, SLOT(gotoSendCoinsPage(QString)));
- // Clicking on "Verify Message" in the address book opens the verify message tab in the Sign/Verify Message dialog
- connect(addressBookPage, SIGNAL(verifyMessage(QString)), this, SLOT(gotoVerifyMessageTab(QString)));
- // Clicking on "Sign Message" in the receive coins page opens the sign message tab in the Sign/Verify Message dialog
- connect(receiveCoinsPage, SIGNAL(signMessage(QString)), this, SLOT(gotoSignMessageTab(QString)));
-
// Install event filter to be able to catch status tip events (QEvent::StatusTip)
this->installEventFilter(this);
-
- gotoOverviewPage();
}
BitcoinGUI::~BitcoinGUI()
{
+ saveWindowGeometry();
if(trayIcon) // Hide tray icon, as deleting will let it linger until quit (on Ubuntu)
trayIcon->hide();
#ifdef Q_OS_MAC
@@ -364,8 +326,7 @@ void BitcoinGUI::setClientModel(ClientModel *clientModel)
// Create system tray menu (or setup the dock menu) that late to prevent users from calling actions,
// while the client has not yet fully loaded
- if(trayIcon)
- createTrayIconMenu();
+ createTrayIconMenu();
// Keep up to date with client
setNumConnections(clientModel->getNumConnections());
@@ -377,39 +338,24 @@ void BitcoinGUI::setClientModel(ClientModel *clientModel)
// Receive and report messages from network/worker thread
connect(clientModel, SIGNAL(message(QString,QString,unsigned int)), this, SLOT(message(QString,QString,unsigned int)));
- overviewPage->setClientModel(clientModel);
rpcConsole->setClientModel(clientModel);
- addressBookPage->setOptionsModel(clientModel->getOptionsModel());
- receiveCoinsPage->setOptionsModel(clientModel->getOptionsModel());
+ walletFrame->setClientModel(clientModel);
}
}
-void BitcoinGUI::setWalletModel(WalletModel *walletModel)
+bool BitcoinGUI::addWallet(const QString& name, WalletModel *walletModel)
{
- this->walletModel = walletModel;
- if(walletModel)
- {
- // Receive and report messages from wallet thread
- connect(walletModel, SIGNAL(message(QString,QString,unsigned int)), this, SLOT(message(QString,QString,unsigned int)));
-
- // 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(walletModel->getEncryptionStatus());
- connect(walletModel, SIGNAL(encryptionStatusChanged(int)), this, SLOT(setEncryptionStatus(int)));
-
- // Balloon pop-up for new transaction
- connect(walletModel->getTransactionTableModel(), SIGNAL(rowsInserted(QModelIndex,int,int)),
- this, SLOT(incomingTransaction(QModelIndex,int,int)));
-
- // Ask for passphrase if needed
- connect(walletModel, SIGNAL(requireUnlock()), this, SLOT(unlockWallet()));
- }
+ return walletFrame->addWallet(name, walletModel);
+}
+
+bool BitcoinGUI::setCurrentWallet(const QString& name)
+{
+ return walletFrame->setCurrentWallet(name);
+}
+
+void BitcoinGUI::removeAllWallets()
+{
+ walletFrame->removeAllWallets();
}
void BitcoinGUI::createTrayIcon()
@@ -429,6 +375,10 @@ void BitcoinGUI::createTrayIconMenu()
{
QMenu *trayIconMenu;
#ifndef Q_OS_MAC
+ // return if trayIcon is unset (only on non-Mac OSes)
+ if (!trayIcon)
+ return;
+
trayIconMenu = new QMenu(this);
trayIcon->setContextMenu(trayIconMenu);
@@ -468,6 +418,28 @@ void BitcoinGUI::trayIconActivated(QSystemTrayIcon::ActivationReason reason)
}
#endif
+void BitcoinGUI::saveWindowGeometry()
+{
+ QSettings settings;
+ settings.setValue("nWindowPos", pos());
+ settings.setValue("nWindowSize", size());
+}
+
+void BitcoinGUI::restoreWindowGeometry()
+{
+ QSettings settings;
+ QPoint pos = settings.value("nWindowPos").toPoint();
+ QSize size = settings.value("nWindowSize", QSize(850, 550)).toSize();
+ if (!pos.x() && !pos.y())
+ {
+ QRect screen = qApp->desktop()->screenGeometry();
+ pos.setX((screen.width()-size.width())/2);
+ pos.setY((screen.height()-size.height())/2);
+ }
+ resize(size);
+ move(pos);
+}
+
void BitcoinGUI::optionsClicked()
{
if(!clientModel || !clientModel->getOptionsModel())
@@ -484,6 +456,41 @@ void BitcoinGUI::aboutClicked()
dlg.exec();
}
+void BitcoinGUI::gotoOverviewPage()
+{
+ if (walletFrame) walletFrame->gotoOverviewPage();
+}
+
+void BitcoinGUI::gotoHistoryPage()
+{
+ if (walletFrame) walletFrame->gotoHistoryPage();
+}
+
+void BitcoinGUI::gotoAddressBookPage()
+{
+ if (walletFrame) walletFrame->gotoAddressBookPage();
+}
+
+void BitcoinGUI::gotoReceiveCoinsPage()
+{
+ if (walletFrame) walletFrame->gotoReceiveCoinsPage();
+}
+
+void BitcoinGUI::gotoSendCoinsPage(QString addr)
+{
+ if (walletFrame) walletFrame->gotoSendCoinsPage(addr);
+}
+
+void BitcoinGUI::gotoSignMessageTab(QString addr)
+{
+ if (walletFrame) walletFrame->gotoSignMessageTab(addr);
+}
+
+void BitcoinGUI::gotoVerifyMessageTab(QString addr)
+{
+ if (walletFrame) walletFrame->gotoSignMessageTab(addr);
+}
+
void BitcoinGUI::setNumConnections(int count)
{
QString icon;
@@ -548,7 +555,7 @@ void BitcoinGUI::setNumBlocks(int count, int nTotalBlocks)
tooltip = tr("Up to date") + QString(".<br>") + tooltip;
labelBlocksIcon->setPixmap(QIcon(":/icons/synced").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
- overviewPage->showOutOfSyncWarning(false);
+ walletFrame->showOutOfSyncWarning(false);
progressBarLabel->setVisible(false);
progressBar->setVisible(false);
@@ -583,7 +590,7 @@ void BitcoinGUI::setNumBlocks(int count, int nTotalBlocks)
syncIconMovie->jumpToNextFrame();
prevBlocks = count;
- overviewPage->showOutOfSyncWarning(true);
+ walletFrame->showOutOfSyncWarning(true);
tooltip += QString("<br>");
tooltip += tr("Last received block was generated %1 ago.").arg(timeBehindText);
@@ -692,23 +699,8 @@ void BitcoinGUI::askFee(qint64 nFeeRequired, bool *payFee)
*payFee = (retval == QMessageBox::Yes);
}
-void BitcoinGUI::incomingTransaction(const QModelIndex& parent, int start, int /*end*/)
+void BitcoinGUI::incomingTransaction(const QString& date, int unit, qint64 amount, const QString& type, const QString& address)
{
- // Prevent balloon-spam when initial block download is in progress
- if(!walletModel || !clientModel || clientModel->inInitialBlockDownload())
- return;
-
- TransactionTableModel *ttm = walletModel->getTransactionTableModel();
-
- QString date = ttm->index(start, TransactionTableModel::Date, parent)
- .data().toString();
- qint64 amount = ttm->index(start, TransactionTableModel::Amount, parent)
- .data(Qt::EditRole).toULongLong();
- QString type = ttm->index(start, TransactionTableModel::Type, parent)
- .data().toString();
- QString address = ttm->index(start, TransactionTableModel::ToAddress, parent)
- .data().toString();
-
// On new transaction, make an info balloon
message((amount)<0 ? tr("Sent transaction") : tr("Incoming transaction"),
tr("Date: %1\n"
@@ -716,80 +708,11 @@ void BitcoinGUI::incomingTransaction(const QModelIndex& parent, int start, int /
"Type: %3\n"
"Address: %4\n")
.arg(date)
- .arg(BitcoinUnits::formatWithUnit(walletModel->getOptionsModel()->getDisplayUnit(), amount, true))
+ .arg(BitcoinUnits::formatWithUnit(unit, amount, true))
.arg(type)
.arg(address), CClientUIInterface::MSG_INFORMATION);
}
-void BitcoinGUI::gotoOverviewPage()
-{
- overviewAction->setChecked(true);
- centralWidget->setCurrentWidget(overviewPage);
-
- exportAction->setEnabled(false);
- disconnect(exportAction, SIGNAL(triggered()), 0, 0);
-}
-
-void BitcoinGUI::gotoHistoryPage()
-{
- historyAction->setChecked(true);
- centralWidget->setCurrentWidget(transactionsPage);
-
- exportAction->setEnabled(true);
- disconnect(exportAction, SIGNAL(triggered()), 0, 0);
- connect(exportAction, SIGNAL(triggered()), transactionView, SLOT(exportClicked()));
-}
-
-void BitcoinGUI::gotoAddressBookPage()
-{
- addressBookAction->setChecked(true);
- centralWidget->setCurrentWidget(addressBookPage);
-
- exportAction->setEnabled(true);
- disconnect(exportAction, SIGNAL(triggered()), 0, 0);
- connect(exportAction, SIGNAL(triggered()), addressBookPage, SLOT(exportClicked()));
-}
-
-void BitcoinGUI::gotoReceiveCoinsPage()
-{
- receiveCoinsAction->setChecked(true);
- centralWidget->setCurrentWidget(receiveCoinsPage);
-
- exportAction->setEnabled(true);
- disconnect(exportAction, SIGNAL(triggered()), 0, 0);
- connect(exportAction, SIGNAL(triggered()), receiveCoinsPage, SLOT(exportClicked()));
-}
-
-void BitcoinGUI::gotoSendCoinsPage(QString addr)
-{
- sendCoinsAction->setChecked(true);
- centralWidget->setCurrentWidget(sendCoinsPage);
-
- exportAction->setEnabled(false);
- disconnect(exportAction, SIGNAL(triggered()), 0, 0);
-
- if(!addr.isEmpty())
- sendCoinsPage->setAddress(addr);
-}
-
-void BitcoinGUI::gotoSignMessageTab(QString addr)
-{
- // call show() in showTab_SM()
- signVerifyMessageDialog->showTab_SM(true);
-
- if(!addr.isEmpty())
- signVerifyMessageDialog->setAddress_SM(addr);
-}
-
-void BitcoinGUI::gotoVerifyMessageTab(QString addr)
-{
- // call show() in showTab_VM()
- signVerifyMessageDialog->showTab_VM(true);
-
- if(!addr.isEmpty())
- signVerifyMessageDialog->setAddress_VM(addr);
-}
-
void BitcoinGUI::dragEnterEvent(QDragEnterEvent *event)
{
// Accept only URIs
@@ -805,13 +728,13 @@ void BitcoinGUI::dropEvent(QDropEvent *event)
QList<QUrl> uris = event->mimeData()->urls();
foreach(const QUrl &uri, uris)
{
- if (sendCoinsPage->handleURI(uri.toString()))
+ if (walletFrame->handleURI(uri.toString()))
nValidUrisFound++;
}
// if valid URIs were found
if (nValidUrisFound)
- gotoSendCoinsPage();
+ walletFrame->gotoSendCoinsPage();
else
message(tr("URI handling"), tr("URI can not be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters."),
CClientUIInterface::ICON_WARNING);
@@ -835,12 +758,7 @@ bool BitcoinGUI::eventFilter(QObject *object, QEvent *event)
void BitcoinGUI::handleURI(QString strURI)
{
// URI has to be valid
- if (sendCoinsPage->handleURI(strURI))
- {
- showNormalIfMinimized();
- gotoSendCoinsPage();
- }
- else
+ if (!walletFrame->handleURI(strURI))
message(tr("URI handling"), tr("URI can not be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters."),
CClientUIInterface::ICON_WARNING);
}
@@ -876,49 +794,22 @@ void BitcoinGUI::setEncryptionStatus(int status)
void BitcoinGUI::encryptWallet(bool status)
{
- if(!walletModel)
- return;
- AskPassphraseDialog dlg(status ? AskPassphraseDialog::Encrypt:
- AskPassphraseDialog::Decrypt, this);
- dlg.setModel(walletModel);
- dlg.exec();
-
- setEncryptionStatus(walletModel->getEncryptionStatus());
+ walletFrame->encryptWallet(status);
}
void BitcoinGUI::backupWallet()
{
- QString saveDir = QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation);
- QString filename = QFileDialog::getSaveFileName(this, tr("Backup Wallet"), saveDir, tr("Wallet Data (*.dat)"));
- if(!filename.isEmpty()) {
- if(!walletModel->backupWallet(filename)) {
- message(tr("Backup Failed"), tr("There was an error trying to save the wallet data to the new location."),
- CClientUIInterface::MSG_ERROR);
- }
- else
- message(tr("Backup Successful"), tr("The wallet data was successfully saved to the new location."),
- CClientUIInterface::MSG_INFORMATION);
- }
+ walletFrame->backupWallet();
}
void BitcoinGUI::changePassphrase()
{
- AskPassphraseDialog dlg(AskPassphraseDialog::ChangePass, this);
- dlg.setModel(walletModel);
- dlg.exec();
+ walletFrame->changePassphrase();
}
void BitcoinGUI::unlockWallet()
{
- if(!walletModel)
- return;
- // Unlock wallet when requested by wallet model
- if(walletModel->getEncryptionStatus() == WalletModel::Locked)
- {
- AskPassphraseDialog dlg(AskPassphraseDialog::Unlock, this);
- dlg.setModel(walletModel);
- dlg.exec();
- }
+ walletFrame->unlockWallet();
}
void BitcoinGUI::showNormalIfMinimized(bool fToggleHidden)
diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h
index 1b3e313fc2..c0cde97b6a 100644
--- a/src/qt/bitcoingui.h
+++ b/src/qt/bitcoingui.h
@@ -3,10 +3,14 @@
#include <QMainWindow>
#include <QSystemTrayIcon>
+#include <QMap>
class TransactionTableModel;
+class WalletFrame;
+class WalletView;
class ClientModel;
class WalletModel;
+class WalletStack;
class TransactionView;
class OverviewPage;
class AddressBookPage;
@@ -15,11 +19,16 @@ class SignVerifyMessageDialog;
class Notificator;
class RPCConsole;
+class CWallet;
+
QT_BEGIN_NAMESPACE
class QLabel;
class QModelIndex;
class QProgressBar;
class QStackedWidget;
+class QUrl;
+class QListWidget;
+class QPushButton;
QT_END_NAMESPACE
/**
@@ -31,6 +40,8 @@ class BitcoinGUI : public QMainWindow
Q_OBJECT
public:
+ static const QString DEFAULT_WALLET;
+
explicit BitcoinGUI(QWidget *parent = 0);
~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
functionality.
*/
- void setWalletModel(WalletModel *walletModel);
+
+ bool addWallet(const QString& name, WalletModel *walletModel);
+ bool setCurrentWallet(const QString& name);
+
+ void removeAllWallets();
protected:
void changeEvent(QEvent *e);
@@ -53,16 +68,7 @@ protected:
private:
ClientModel *clientModel;
- WalletModel *walletModel;
-
- QStackedWidget *centralWidget;
-
- OverviewPage *overviewPage;
- QWidget *transactionsPage;
- AddressBookPage *addressBookPage;
- AddressBookPage *receiveCoinsPage;
- SendCoinsDialog *sendCoinsPage;
- SignVerifyMessageDialog *signVerifyMessageDialog;
+ WalletFrame *walletFrame;
QLabel *labelEncryptionIcon;
QLabel *labelConnectionsIcon;
@@ -108,6 +114,10 @@ private:
void createTrayIcon();
/** Create system tray menu (or setup the dock menu) */
void createTrayIconMenu();
+ /** Save window size and position */
+ void saveWindowGeometry();
+ /** Restore window size and position */
+ void restoreWindowGeometry();
public slots:
/** Set number of connections shown in the UI */
@@ -139,6 +149,9 @@ public slots:
void askFee(qint64 nFeeRequired, bool *payFee);
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:
/** Switch to overview (home) page */
void gotoOverviewPage();
@@ -164,11 +177,6 @@ private slots:
/** Handle tray icon clicked */
void trayIconActivated(QSystemTrayIcon::ActivationReason reason);
#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 */
void encryptWallet(bool status);
/** Backup the wallet */
diff --git a/src/qt/forms/overviewpage.ui b/src/qt/forms/overviewpage.ui
index 970e6c671d..57aa624cc2 100644
--- a/src/qt/forms/overviewpage.ui
+++ b/src/qt/forms/overviewpage.ui
@@ -49,7 +49,6 @@
<widget class="QLabel" name="label_5">
<property name="font">
<font>
- <pointsize>11</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
@@ -159,23 +158,6 @@
</property>
</widget>
</item>
- <item row="3" column="0">
- <widget class="QLabel" name="label_2">
- <property name="text">
- <string>Number of transactions:</string>
- </property>
- </widget>
- </item>
- <item row="3" column="1">
- <widget class="QLabel" name="labelNumTransactions">
- <property name="toolTip">
- <string>Total number of transactions in wallet</string>
- </property>
- <property name="text">
- <string notr="true">0</string>
- </property>
- </widget>
- </item>
<item row="2" column="0">
<widget class="QLabel" name="labelImmatureText">
<property name="text">
diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp
index 30ad8ef66b..06ccde3782 100644
--- a/src/qt/guiutil.cpp
+++ b/src/qt/guiutil.cpp
@@ -161,7 +161,7 @@ void copyEntryData(QAbstractItemView *view, int column, int role)
if(!selection.isEmpty())
{
// Copy first item
- QApplication::clipboard()->setText(selection.at(0).data(role).toString());
+ QApplication::clipboard()->setText(selection.at(0).data(role).toString(),QClipboard::Selection);
}
}
diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp
index 8f1ff5325e..528c93bdc1 100644
--- a/src/qt/overviewpage.cpp
+++ b/src/qt/overviewpage.cpp
@@ -147,11 +147,6 @@ void OverviewPage::setBalance(qint64 balance, qint64 unconfirmedBalance, qint64
ui->labelImmatureText->setVisible(showImmature);
}
-void OverviewPage::setNumTransactions(int count)
-{
- ui->labelNumTransactions->setText(QLocale::system().toString(count));
-}
-
void OverviewPage::setClientModel(ClientModel *model)
{
this->clientModel = model;
@@ -183,9 +178,6 @@ void OverviewPage::setWalletModel(WalletModel *model)
setBalance(model->getBalance(), model->getUnconfirmedBalance(), model->getImmatureBalance());
connect(model, SIGNAL(balanceChanged(qint64, qint64, qint64)), this, SLOT(setBalance(qint64, qint64, qint64)));
- setNumTransactions(model->getNumTransactions());
- connect(model, SIGNAL(numTransactionsChanged(int)), this, SLOT(setNumTransactions(int)));
-
connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));
}
diff --git a/src/qt/overviewpage.h b/src/qt/overviewpage.h
index b287f479f8..59ba3c66bb 100644
--- a/src/qt/overviewpage.h
+++ b/src/qt/overviewpage.h
@@ -30,7 +30,6 @@ public:
public slots:
void setBalance(qint64 balance, qint64 unconfirmedBalance, qint64 immatureBalance);
- void setNumTransactions(int count);
signals:
void transactionClicked(const QModelIndex &index);
diff --git a/src/qt/transactionview.cpp b/src/qt/transactionview.cpp
index e7c384161c..9240b71c71 100644
--- a/src/qt/transactionview.cpp
+++ b/src/qt/transactionview.cpp
@@ -123,6 +123,7 @@ TransactionView::TransactionView(QWidget *parent) :
QAction *copyAddressAction = new QAction(tr("Copy address"), this);
QAction *copyLabelAction = new QAction(tr("Copy label"), this);
QAction *copyAmountAction = new QAction(tr("Copy amount"), this);
+ QAction *copyTxIDAction = new QAction(tr("Copy transaction ID"), this);
QAction *editLabelAction = new QAction(tr("Edit label"), this);
QAction *showDetailsAction = new QAction(tr("Show transaction details"), this);
@@ -130,6 +131,7 @@ TransactionView::TransactionView(QWidget *parent) :
contextMenu->addAction(copyAddressAction);
contextMenu->addAction(copyLabelAction);
contextMenu->addAction(copyAmountAction);
+ contextMenu->addAction(copyTxIDAction);
contextMenu->addAction(editLabelAction);
contextMenu->addAction(showDetailsAction);
@@ -145,6 +147,7 @@ TransactionView::TransactionView(QWidget *parent) :
connect(copyAddressAction, SIGNAL(triggered()), this, SLOT(copyAddress()));
connect(copyLabelAction, SIGNAL(triggered()), this, SLOT(copyLabel()));
connect(copyAmountAction, SIGNAL(triggered()), this, SLOT(copyAmount()));
+ connect(copyTxIDAction, SIGNAL(triggered()), this, SLOT(copyTxID()));
connect(editLabelAction, SIGNAL(triggered()), this, SLOT(editLabel()));
connect(showDetailsAction, SIGNAL(triggered()), this, SLOT(showDetails()));
}
@@ -309,6 +312,11 @@ void TransactionView::copyAmount()
GUIUtil::copyEntryData(transactionView, 0, TransactionTableModel::FormattedAmountRole);
}
+void TransactionView::copyTxID()
+{
+ GUIUtil::copyEntryData(transactionView, 0, TransactionTableModel::TxIDRole);
+}
+
void TransactionView::editLabel()
{
if(!transactionView->selectionModel() ||!model)
diff --git a/src/qt/transactionview.h b/src/qt/transactionview.h
index e61515fdae..bb41a83e32 100644
--- a/src/qt/transactionview.h
+++ b/src/qt/transactionview.h
@@ -66,6 +66,7 @@ private slots:
void editLabel();
void copyLabel();
void copyAmount();
+ void copyTxID();
signals:
void doubleClicked(const QModelIndex&);
diff --git a/src/qt/walletframe.cpp b/src/qt/walletframe.cpp
new file mode 100644
index 0000000000..b5947caf3a
--- /dev/null
+++ b/src/qt/walletframe.cpp
@@ -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(QString addr)
+{
+ walletStack->gotoSendCoinsPage(addr);
+}
+
+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();
+}
diff --git a/src/qt/walletframe.h b/src/qt/walletframe.h
new file mode 100644
index 0000000000..3649185e8a
--- /dev/null
+++ b/src/qt/walletframe.h
@@ -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(QString addr = "");
+
+ /** 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 \ No newline at end of file
diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp
index 9d5a2c04ff..20535a451d 100644
--- a/src/qt/walletmodel.cpp
+++ b/src/qt/walletmodel.cpp
@@ -56,6 +56,8 @@ int WalletModel::getNumTransactions() const
int numTransactions = 0;
{
LOCK(wallet->cs_wallet);
+ // the size of mapWallet contains the number of unique transaction IDs
+ // (e.g. payments to yourself generate 2 transactions, but both share the same transaction ID)
numTransactions = wallet->mapWallet.size();
}
return numTransactions;
diff --git a/src/qt/walletstack.cpp b/src/qt/walletstack.cpp
new file mode 100644
index 0000000000..42d86956be
--- /dev/null
+++ b/src/qt/walletstack.cpp
@@ -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(QString addr)
+{
+ QMap<QString, WalletView*>::const_iterator i;
+ for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i)
+ i.value()->gotoSendCoinsPage(addr);
+}
+
+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();
+}
diff --git a/src/qt/walletstack.h b/src/qt/walletstack.h
new file mode 100644
index 0000000000..ea4cc121d1
--- /dev/null
+++ b/src/qt/walletstack.h
@@ -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(QString addr = "");
+
+ /** 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
diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp
new file mode 100644
index 0000000000..6be34e5ff4
--- /dev/null
+++ b/src/qt/walletview.cpp
@@ -0,0 +1,359 @@
+/*
+ * 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 "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)));
+
+ 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(QString addr)
+{
+ sendCoinsAction->setChecked(true);
+ setCurrentWidget(sendCoinsPage);
+
+ exportAction->setEnabled(false);
+ disconnect(exportAction, SIGNAL(triggered()), 0, 0);
+
+ if(!addr.isEmpty())
+ sendCoinsPage->setAddress(addr);
+}
+
+void WalletView::gotoSignMessageTab(QString addr)
+{
+ // call show() in showTab_SM()
+ signVerifyMessageDialog->showTab_SM(true);
+
+ if(!addr.isEmpty())
+ signVerifyMessageDialog->setAddress_SM(addr);
+}
+
+void WalletView::gotoVerifyMessageTab(QString addr)
+{
+ // call show() in showTab_VM()
+ signVerifyMessageDialog->showTab_VM(true);
+
+ if(!addr.isEmpty())
+ signVerifyMessageDialog->setAddress_VM(addr);
+}
+
+bool WalletView::handleURI(const QString& strURI)
+{
+ // URI has to be valid
+ if (sendCoinsPage->handleURI(strURI))
+ {
+ gotoSendCoinsPage();
+ return true;
+ }
+ else
+ return false;
+}
+
+void WalletView::showOutOfSyncWarning(bool fShow)
+{
+ overviewPage->showOutOfSyncWarning(fShow);
+}
+
+void WalletView::setEncryptionStatus()
+{
+ gui->setEncryptionStatus(walletModel->getEncryptionStatus());
+}
+
+void WalletView::encryptWallet(bool status)
+{
+ if(!walletModel)
+ return;
+ AskPassphraseDialog dlg(status ? AskPassphraseDialog::Encrypt:
+ AskPassphraseDialog::Decrypt, this);
+ dlg.setModel(walletModel);
+ dlg.exec();
+
+ setEncryptionStatus();
+}
+
+void WalletView::backupWallet()
+{
+ 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();
+ }
+}
diff --git a/src/qt/walletview.h b/src/qt/walletview.h
new file mode 100644
index 0000000000..caa51d7c3a
--- /dev/null
+++ b/src/qt/walletview.h
@@ -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(QString addr = "");
+
+ /** 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