aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--bitcoin-qt.pro12
-rw-r--r--multiwallet-qt.txt53
-rw-r--r--src/init.cpp9
-rw-r--r--src/qt/addressbookpage.cpp16
-rw-r--r--src/qt/addressbookpage.h3
-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.cpp300
-rw-r--r--src/qt/bitcoingui.h42
-rw-r--r--src/qt/bitcoinstrings.cpp10
-rw-r--r--src/qt/guiutil.cpp2
-rw-r--r--src/qt/locale/bitcoin_en.ts241
-rw-r--r--src/qt/res/bitcoin-qt.rc2
-rw-r--r--src/qt/sendcoinsdialog.cpp20
-rw-r--r--src/qt/sendcoinsdialog.h1
-rw-r--r--src/qt/sendcoinsentry.cpp6
-rw-r--r--src/qt/sendcoinsentry.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/walletstack.cpp155
-rw-r--r--src/qt/walletstack.h102
-rw-r--r--src/qt/walletview.cpp354
-rw-r--r--src/qt/walletview.h132
27 files changed, 1335 insertions, 351 deletions
diff --git a/README.md b/README.md
index f1a860953f..a50736d4ed 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@ Bitcoin integration/staging tree
http://www.bitcoin.org
-Copyright (c) 2009-2012 Bitcoin Developers
+Copyright (c) 2009-2013 Bitcoin Developers
What is Bitcoin?
----------------
diff --git a/bitcoin-qt.pro b/bitcoin-qt.pro
index 5042adfbdf..d518cf3b16 100644
--- a/bitcoin-qt.pro
+++ b/bitcoin-qt.pro
@@ -30,10 +30,8 @@ contains(RELEASE, 1) {
macx:QMAKE_OBJECTIVE_CFLAGS += -mmacosx-version-min=10.5 -arch i386 -isysroot /Developer/SDKs/MacOSX10.5.sdk
!win32:!macx {
- # Linux: static link
+ # Linux: static link and extra security (see: https://wiki.debian.org/Hardening)
LIBS += -Wl,-Bstatic -Wl,-z,relro -Wl,-z,now
- # for extra security (see: https://wiki.debian.org/Hardening)
- QMAKE_CXXFLAGS *= -D_FORTIFY_SOURCE=2
}
}
@@ -44,6 +42,8 @@ contains(RELEASE, 1) {
# Exclude on Windows cross compile with MinGW 4.2.x, as it will result in a non-working executable!
# This can be enabled for Windows, when we switch to MinGW >= 4.4.x.
}
+# for extra security (see: https://wiki.debian.org/Hardening): this flag is GCC compiler-specific
+QMAKE_CXXFLAGS *= -D_FORTIFY_SOURCE=2
# for extra security on Windows: enable ASLR and DEP via GCC linker flags
win32:QMAKE_LFLAGS *= -Wl,--dynamicbase -Wl,--nxcompat
# on Windows: enable GCC large address aware linker flag
@@ -186,6 +186,9 @@ HEADERS += src/qt/bitcoingui.h \
src/qt/transactionfilterproxy.h \
src/qt/transactionview.h \
src/qt/walletmodel.h \
+ src/qt/walletview.h \
+ src/qt/walletstack.h \
+ src/qt/walletframe.h \
src/bitcoinrpc.h \
src/qt/overviewpage.h \
src/qt/csvmodelwriter.h \
@@ -250,6 +253,9 @@ SOURCES += src/qt/bitcoin.cpp \
src/qt/transactionfilterproxy.cpp \
src/qt/transactionview.cpp \
src/qt/walletmodel.cpp \
+ src/qt/walletview.cpp \
+ src/qt/walletstack.cpp \
+ src/qt/walletframe.cpp \
src/bitcoinrpc.cpp \
src/rpcdump.cpp \
src/rpcnet.cpp \
diff --git a/multiwallet-qt.txt b/multiwallet-qt.txt
new file mode 100644
index 0000000000..8394080db0
--- /dev/null
+++ b/multiwallet-qt.txt
@@ -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();
diff --git a/src/init.cpp b/src/init.cpp
index b61d1b9358..7c72982dd2 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -609,13 +609,11 @@ bool AppInit2()
// ********************************************************* Step 5: verify wallet database integrity
- uiInterface.InitMessage(_("Verifying wallet integrity..."));
+ uiInterface.InitMessage(_("Verifying wallet..."));
if (!bitdb.Open(GetDataDir()))
{
- string msg = strprintf(_("Error initializing database environment %s!"
- " To recover, BACKUP THAT DIRECTORY, then remove"
- " everything from it except for wallet.dat."), strDataDir.c_str());
+ string msg = strprintf(_("Error initializing wallet database environment %s!"), strDataDir.c_str());
return InitError(msg);
}
@@ -827,7 +825,7 @@ bool AppInit2()
break;
}
- uiInterface.InitMessage(_("Verifying database..."));
+ uiInterface.InitMessage(_("Verifying blocks..."));
if (!VerifyDB()) {
strLoadError = _("Corrupted block database detected");
break;
@@ -986,7 +984,6 @@ bool AppInit2()
// ********************************************************* Step 9: import blocks
// scan for better chains in the block chain database, that are not yet connected in the active best chain
- uiInterface.InitMessage(_("Importing blocks from block database..."));
CValidationState state;
if (!ConnectBestBlock(state))
strErrors << "Failed to connect best block";
diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp
index b53a37fc22..9e35e51bbf 100644
--- a/src/qt/addressbookpage.cpp
+++ b/src/qt/addressbookpage.cpp
@@ -65,6 +65,7 @@ AddressBookPage::AddressBookPage(Mode mode, Tabs tab, QWidget *parent) :
QAction *copyAddressAction = new QAction(ui->copyToClipboard->text(), this);
QAction *copyLabelAction = new QAction(tr("Copy &Label"), this);
QAction *editAction = new QAction(tr("&Edit"), this);
+ QAction *sendCoinsAction = new QAction(tr("Send &Coins"), this);
QAction *showQRCodeAction = new QAction(ui->showQRCode->text(), this);
QAction *signMessageAction = new QAction(ui->signMessage->text(), this);
QAction *verifyMessageAction = new QAction(ui->verifyMessage->text(), this);
@@ -78,6 +79,8 @@ AddressBookPage::AddressBookPage(Mode mode, Tabs tab, QWidget *parent) :
if(tab == SendingTab)
contextMenu->addAction(deleteAction);
contextMenu->addSeparator();
+ if(tab == SendingTab)
+ contextMenu->addAction(sendCoinsAction);
#ifdef USE_QRCODE
contextMenu->addAction(showQRCodeAction);
#endif
@@ -91,6 +94,7 @@ AddressBookPage::AddressBookPage(Mode mode, Tabs tab, QWidget *parent) :
connect(copyLabelAction, SIGNAL(triggered()), this, SLOT(onCopyLabelAction()));
connect(editAction, SIGNAL(triggered()), this, SLOT(onEditAction()));
connect(deleteAction, SIGNAL(triggered()), this, SLOT(on_deleteButton_clicked()));
+ connect(sendCoinsAction, SIGNAL(triggered()), this, SLOT(onSendCoins_clicked()));
connect(showQRCodeAction, SIGNAL(triggered()), this, SLOT(on_showQRCode_clicked()));
connect(signMessageAction, SIGNAL(triggered()), this, SLOT(on_signMessage_clicked()));
connect(verifyMessageAction, SIGNAL(triggered()), this, SLOT(on_verifyMessage_clicked()));
@@ -206,6 +210,18 @@ void AddressBookPage::on_verifyMessage_clicked()
}
}
+void AddressBookPage::onSendCoins_clicked()
+{
+ QTableView *table = ui->tableView;
+ QModelIndexList indexes = table->selectionModel()->selectedRows(AddressTableModel::Address);
+
+ foreach (QModelIndex index, indexes)
+ {
+ QString address = index.data().toString();
+ emit sendCoins(address);
+ }
+}
+
void AddressBookPage::on_newAddressButton_clicked()
{
if(!model)
diff --git a/src/qt/addressbookpage.h b/src/qt/addressbookpage.h
index c676d1e941..c6653a5e8a 100644
--- a/src/qt/addressbookpage.h
+++ b/src/qt/addressbookpage.h
@@ -68,6 +68,8 @@ private slots:
void on_signMessage_clicked();
/** Open the verify message tab in the Sign/Verify Message dialog with currently selected address */
void on_verifyMessage_clicked();
+ /** Open send coins dialog for currently selected address (no button) */
+ void onSendCoins_clicked();
/** Generate a QR Code from the currently selected address */
void on_showQRCode_clicked();
/** Copy label of currently selected address entry to clipboard (no button) */
@@ -85,6 +87,7 @@ private slots:
signals:
void signMessage(QString addr);
void verifyMessage(QString addr);
+ void sendCoins(QString addr);
};
#endif // ADDRESSBOOKPAGE_H
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 4f97a4815f..eff8e667f6 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,29 +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 "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)));
-
// 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
@@ -241,7 +205,7 @@ void BitcoinGUI::createActions()
connect(historyAction, SIGNAL(triggered()), this, SLOT(gotoHistoryPage()));
connect(addressBookAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
connect(addressBookAction, SIGNAL(triggered()), this, SLOT(gotoAddressBookPage()));
-
+
quitAction = new QAction(QIcon(":/icons/quit"), tr("E&xit"), this);
quitAction->setStatusTip(tr("Quit application"));
quitAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q));
@@ -375,39 +339,23 @@ void BitcoinGUI::setClientModel(ClientModel *clientModel)
// Receive and report messages from network/worker thread
connect(clientModel, SIGNAL(message(QString,QString,unsigned int)), this, SLOT(message(QString,QString,unsigned int)));
- overviewPage->setClientModel(clientModel);
- rpcConsole->setClientModel(clientModel);
- addressBookPage->setOptionsModel(clientModel->getOptionsModel());
- receiveCoinsPage->setOptionsModel(clientModel->getOptionsModel());
+ walletFrame->setClientModel(clientModel);
}
}
-void BitcoinGUI::setWalletModel(WalletModel *walletModel)
+bool BitcoinGUI::addWallet(const QString& name, WalletModel *walletModel)
{
- this->walletModel = walletModel;
- if(walletModel)
- {
- // Receive and report messages from wallet thread
- connect(walletModel, SIGNAL(message(QString,QString,unsigned int)), this, SLOT(message(QString,QString,unsigned int)));
-
- // 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()
@@ -466,6 +414,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())
@@ -482,6 +452,41 @@ void BitcoinGUI::aboutClicked()
dlg.exec();
}
+void BitcoinGUI::gotoOverviewPage()
+{
+ if (walletFrame) walletFrame->gotoOverviewPage();
+}
+
+void BitcoinGUI::gotoHistoryPage()
+{
+ if (walletFrame) walletFrame->gotoHistoryPage();
+}
+
+void BitcoinGUI::gotoAddressBookPage()
+{
+ if (walletFrame) walletFrame->gotoAddressBookPage();
+}
+
+void BitcoinGUI::gotoReceiveCoinsPage()
+{
+ if (walletFrame) walletFrame->gotoReceiveCoinsPage();
+}
+
+void BitcoinGUI::gotoSendCoinsPage()
+{
+ if (walletFrame) walletFrame->gotoSendCoinsPage();
+}
+
+void BitcoinGUI::gotoSignMessageTab(QString addr)
+{
+ if (walletFrame) walletFrame->gotoSignMessageTab(addr);
+}
+
+void BitcoinGUI::gotoVerifyMessageTab(QString addr)
+{
+ if (walletFrame) walletFrame->gotoSignMessageTab(addr);
+}
+
void BitcoinGUI::setNumConnections(int count)
{
QString icon;
@@ -546,7 +551,7 @@ void BitcoinGUI::setNumBlocks(int count, int nTotalBlocks)
tooltip = tr("Up to date") + QString(".<br>") + tooltip;
labelBlocksIcon->setPixmap(QIcon(":/icons/synced").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
- overviewPage->showOutOfSyncWarning(false);
+ walletFrame->showOutOfSyncWarning(false);
progressBarLabel->setVisible(false);
progressBar->setVisible(false);
@@ -581,7 +586,7 @@ void BitcoinGUI::setNumBlocks(int count, int nTotalBlocks)
syncIconMovie->jumpToNextFrame();
prevBlocks = count;
- overviewPage->showOutOfSyncWarning(true);
+ walletFrame->showOutOfSyncWarning(true);
tooltip += QString("<br>");
tooltip += tr("Last received block was generated %1 ago.").arg(timeBehindText);
@@ -690,101 +695,20 @@ void BitcoinGUI::askFee(qint64 nFeeRequired, bool *payFee)
*payFee = (retval == QMessageBox::Yes);
}
-void BitcoinGUI::incomingTransaction(const QModelIndex& parent, int start, int /*end*/)
+void BitcoinGUI::incomingTransaction(const QString& date, int unit, qint64 amount, const QString& type, const QString& address)
{
- // Prevent balloon-spam when initial block download is in progress
- if(!walletModel || !clientModel || clientModel->inInitialBlockDownload())
- return;
-
- TransactionTableModel *ttm = walletModel->getTransactionTableModel();
-
- QString date = ttm->index(start, TransactionTableModel::Date, parent)
- .data().toString();
- qint64 amount = ttm->index(start, TransactionTableModel::Amount, parent)
- .data(Qt::EditRole).toULongLong();
- QString type = ttm->index(start, TransactionTableModel::Type, parent)
- .data().toString();
- QString address = ttm->index(start, TransactionTableModel::ToAddress, parent)
- .data().toString();
-
- // On new transaction, make an info balloon
+ // On new transaction, make an info balloon
message((amount)<0 ? tr("Sent transaction") : tr("Incoming transaction"),
tr("Date: %1\n"
"Amount: %2\n"
"Type: %3\n"
"Address: %4\n")
.arg(date)
- .arg(BitcoinUnits::formatWithUnit(walletModel->getOptionsModel()->getDisplayUnit(), amount, true))
+ .arg(BitcoinUnits::formatWithUnit(unit, amount, true))
.arg(type)
.arg(address), CClientUIInterface::MSG_INFORMATION);
}
-void BitcoinGUI::gotoOverviewPage()
-{
- overviewAction->setChecked(true);
- centralWidget->setCurrentWidget(overviewPage);
-
- exportAction->setEnabled(false);
- disconnect(exportAction, SIGNAL(triggered()), 0, 0);
-}
-
-void BitcoinGUI::gotoHistoryPage()
-{
- historyAction->setChecked(true);
- centralWidget->setCurrentWidget(transactionsPage);
-
- exportAction->setEnabled(true);
- disconnect(exportAction, SIGNAL(triggered()), 0, 0);
- connect(exportAction, SIGNAL(triggered()), transactionView, SLOT(exportClicked()));
-}
-
-void BitcoinGUI::gotoAddressBookPage()
-{
- addressBookAction->setChecked(true);
- centralWidget->setCurrentWidget(addressBookPage);
-
- exportAction->setEnabled(true);
- disconnect(exportAction, SIGNAL(triggered()), 0, 0);
- connect(exportAction, SIGNAL(triggered()), addressBookPage, SLOT(exportClicked()));
-}
-
-void BitcoinGUI::gotoReceiveCoinsPage()
-{
- receiveCoinsAction->setChecked(true);
- centralWidget->setCurrentWidget(receiveCoinsPage);
-
- exportAction->setEnabled(true);
- disconnect(exportAction, SIGNAL(triggered()), 0, 0);
- connect(exportAction, SIGNAL(triggered()), receiveCoinsPage, SLOT(exportClicked()));
-}
-
-void BitcoinGUI::gotoSendCoinsPage()
-{
- sendCoinsAction->setChecked(true);
- centralWidget->setCurrentWidget(sendCoinsPage);
-
- exportAction->setEnabled(false);
- disconnect(exportAction, SIGNAL(triggered()), 0, 0);
-}
-
-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
@@ -800,13 +724,13 @@ void BitcoinGUI::dropEvent(QDropEvent *event)
QList<QUrl> uris = event->mimeData()->urls();
foreach(const QUrl &uri, uris)
{
- if (sendCoinsPage->handleURI(uri.toString()))
+ if (walletFrame->handleURI(uri.toString()))
nValidUrisFound++;
}
// if valid URIs were found
if (nValidUrisFound)
- gotoSendCoinsPage();
+ walletFrame->gotoSendCoinsPage();
else
message(tr("URI handling"), tr("URI can not be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters."),
CClientUIInterface::ICON_WARNING);
@@ -830,12 +754,7 @@ bool BitcoinGUI::eventFilter(QObject *object, QEvent *event)
void BitcoinGUI::handleURI(QString strURI)
{
// URI has to be valid
- if (sendCoinsPage->handleURI(strURI))
- {
- showNormalIfMinimized();
- gotoSendCoinsPage();
- }
- else
+ if (!walletFrame->handleURI(strURI))
message(tr("URI handling"), tr("URI can not be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters."),
CClientUIInterface::ICON_WARNING);
}
@@ -871,49 +790,22 @@ void BitcoinGUI::setEncryptionStatus(int status)
void BitcoinGUI::encryptWallet(bool status)
{
- if(!walletModel)
- return;
- AskPassphraseDialog dlg(status ? AskPassphraseDialog::Encrypt:
- AskPassphraseDialog::Decrypt, this);
- dlg.setModel(walletModel);
- dlg.exec();
-
- setEncryptionStatus(walletModel->getEncryptionStatus());
+ walletFrame->encryptWallet(status);
}
void BitcoinGUI::backupWallet()
{
- QString saveDir = QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation);
- QString filename = QFileDialog::getSaveFileName(this, tr("Backup Wallet"), saveDir, tr("Wallet Data (*.dat)"));
- if(!filename.isEmpty()) {
- if(!walletModel->backupWallet(filename)) {
- message(tr("Backup Failed"), tr("There was an error trying to save the wallet data to the new location."),
- CClientUIInterface::MSG_ERROR);
- }
- else
- message(tr("Backup Successful"), tr("The wallet data was successfully saved to the new location."),
- CClientUIInterface::MSG_INFORMATION);
- }
+ walletFrame->backupWallet();
}
void BitcoinGUI::changePassphrase()
{
- AskPassphraseDialog dlg(AskPassphraseDialog::ChangePass, this);
- dlg.setModel(walletModel);
- dlg.exec();
+ walletFrame->changePassphrase();
}
void BitcoinGUI::unlockWallet()
{
- if(!walletModel)
- return;
- // Unlock wallet when requested by wallet model
- if(walletModel->getEncryptionStatus() == WalletModel::Locked)
- {
- AskPassphraseDialog dlg(AskPassphraseDialog::Unlock, this);
- dlg.setModel(walletModel);
- dlg.exec();
- }
+ walletFrame->unlockWallet();
}
void BitcoinGUI::showNormalIfMinimized(bool fToggleHidden)
diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h
index b992bfdc69..750e97104c 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;
@@ -88,7 +94,7 @@ private:
QAction *changePassphraseAction;
QAction *aboutQtAction;
QAction *openRPCConsoleAction;
-
+
QSystemTrayIcon *trayIcon;
Notificator *notificator;
TransactionView *transactionView;
@@ -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/bitcoinstrings.cpp b/src/qt/bitcoinstrings.cpp
index 2c3d859c82..dc506f0497 100644
--- a/src/qt/bitcoinstrings.cpp
+++ b/src/qt/bitcoinstrings.cpp
@@ -31,8 +31,6 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
"Cannot obtain a lock on data directory %s. Bitcoin is probably already "
"running."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
-"Corrupted block database detected. Please restart the client with -reindex."),
-QT_TRANSLATE_NOOP("bitcoin-core", ""
"Error initializing database environment %s! To recover, BACKUP THAT "
"DIRECTORY, then remove everything from it except for wallet.dat."),
QT_TRANSLATE_NOOP("bitcoin-core", ""
@@ -43,6 +41,9 @@ QT_TRANSLATE_NOOP("bitcoin-core", ""
"Error: This transaction requires a transaction fee of at least %s because of "
"its amount, complexity, or use of recently received funds!"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
+"Execute command when a wallet transaction changes (%s in cmd is replaced by "
+"TxID)"),
+QT_TRANSLATE_NOOP("bitcoin-core", ""
"Execute command when the best block changes (%s in cmd is replaced by block "
"hash)"),
QT_TRANSLATE_NOOP("bitcoin-core", ""
@@ -97,7 +98,9 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Cannot write default address"),
QT_TRANSLATE_NOOP("bitcoin-core", "Connect only to the specified node(s)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Connect through socks proxy"),
QT_TRANSLATE_NOOP("bitcoin-core", "Connect to a node to retrieve peer addresses, and disconnect"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Corrupted block database detected"),
QT_TRANSLATE_NOOP("bitcoin-core", "Discover own IP address (default: 1 when listening and no -externalip)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Do you want to rebuild the block database now?"),
QT_TRANSLATE_NOOP("bitcoin-core", "Don't generate coins"),
QT_TRANSLATE_NOOP("bitcoin-core", "Done loading"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error initializing block database"),
@@ -105,6 +108,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Error loading block database"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat: Wallet corrupted"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat: Wallet requires newer version of Bitcoin"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Error opening block database"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error: Disk space is low!"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error: Transaction creation failed!"),
@@ -190,7 +194,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Use UPnP to map the listening port (default:
QT_TRANSLATE_NOOP("bitcoin-core", "Use proxy to reach tor hidden services (default: same as -proxy)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Use the test network"),
QT_TRANSLATE_NOOP("bitcoin-core", "Username for JSON-RPC connections"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Verifying block database integrity..."),
+QT_TRANSLATE_NOOP("bitcoin-core", "Verifying database..."),
QT_TRANSLATE_NOOP("bitcoin-core", "Verifying wallet integrity..."),
QT_TRANSLATE_NOOP("bitcoin-core", "Wallet needed to be rewritten: restart Bitcoin to complete"),
QT_TRANSLATE_NOOP("bitcoin-core", "Warning"),
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/locale/bitcoin_en.ts b/src/qt/locale/bitcoin_en.ts
index 39062d0a2c..e05c018c27 100644
--- a/src/qt/locale/bitcoin_en.ts
+++ b/src/qt/locale/bitcoin_en.ts
@@ -414,16 +414,8 @@ This product includes software developed by the OpenSSL Project for use in the O
<source>Reindexing blocks on disk...</source>
<translation>Reindexing blocks on disk...</translation>
</message>
- <message numerus="yes">
- <location line="+10"/>
- <source>~%n block(s) remaining</source>
- <translation>
- <numerusform>~%n block remaining</numerusform>
- <numerusform>~%n blocks remaining</numerusform>
- </translation>
- </message>
<message>
- <location line="-265"/>
+ <location line="-255"/>
<source>&amp;Export...</source>
<translation>&amp;Export...</translation>
</message>
@@ -469,12 +461,12 @@ This product includes software developed by the OpenSSL Project for use in the O
</message>
<message>
<location line="-196"/>
- <location line="+538"/>
+ <location line="+529"/>
<source>Bitcoin</source>
<translation>Bitcoin</translation>
</message>
<message>
- <location line="-538"/>
+ <location line="-529"/>
<source>Wallet</source>
<translation>Wallet</translation>
</message>
@@ -553,17 +545,56 @@ This product includes software developed by the OpenSSL Project for use in the O
</translation>
</message>
<message>
- <location line="+45"/>
- <source>Processed %1 of %2 blocks of transaction history (%3% done).</source>
- <translation>Processed %1 of %2 blocks of transaction history (%3% done).</translation>
+ <location line="+39"/>
+ <source>Processed %1 of %2 (estimated) blocks of transaction history.</source>
+ <translation>Processed %1 of %2 (estimated) blocks of transaction history.</translation>
</message>
<message>
- <location line="+7"/>
+ <location line="+4"/>
<source>Processed %1 blocks of transaction history.</source>
<translation>Processed %1 blocks of transaction history.</translation>
</message>
+ <message numerus="yes">
+ <location line="+20"/>
+ <source>%n hour(s)</source>
+ <translation>
+ <numerusform>%n hour</numerusform>
+ <numerusform>%n hours</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location line="+4"/>
+ <source>%n day(s)</source>
+ <translation>
+ <numerusform>%n day</numerusform>
+ <numerusform>%n days</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <location line="+4"/>
+ <source>%n week(s)</source>
+ <translation>
+ <numerusform>%n week</numerusform>
+ <numerusform>%n weeks</numerusform>
+ </translation>
+ </message>
<message>
- <location line="+70"/>
+ <location line="+5"/>
+ <source>%1 behind</source>
+ <translation>%1 behind</translation>
+ </message>
+ <message>
+ <location line="+14"/>
+ <source>Last received block was generated %1 ago.</source>
+ <translation>Last received block was generated %1 ago.</translation>
+ </message>
+ <message>
+ <location line="+2"/>
+ <source>Transactions after this will not yet be visible.</source>
+ <translation>Transactions after this will not yet be visible.</translation>
+ </message>
+ <message>
+ <location line="+21"/>
<source>Error</source>
<translation>Error</translation>
</message>
@@ -578,7 +609,7 @@ This product includes software developed by the OpenSSL Project for use in the O
<translation>Information</translation>
</message>
<message>
- <location line="+66"/>
+ <location line="+68"/>
<source>This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee?</source>
<translation>This transaction is over the size limit. You can still send it for a fee of %1, which goes to the nodes that process your transaction and helps to support the network. Do you want to pay the fee?</translation>
</message>
@@ -592,55 +623,18 @@ This product includes software developed by the OpenSSL Project for use in the O
<source>The wallet data was successfully saved to the new location.</source>
<translation>The wallet data was successfully saved to the new location.</translation>
</message>
- <message numerus="yes">
- <location line="-338"/>
- <source>%n second(s) ago</source>
- <translation>
- <numerusform>%n second ago</numerusform>
- <numerusform>%n seconds ago</numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <location line="+4"/>
- <source>%n minute(s) ago</source>
- <translation>
- <numerusform>%n minute ago</numerusform>
- <numerusform>%n minutes ago</numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <location line="+4"/>
- <source>%n hour(s) ago</source>
- <translation>
- <numerusform>%n hour ago</numerusform>
- <numerusform>%n hours ago</numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <location line="+4"/>
- <source>%n day(s) ago</source>
- <translation>
- <numerusform>%n day ago</numerusform>
- <numerusform>%n days ago</numerusform>
- </translation>
- </message>
<message>
- <location line="+6"/>
+ <location line="-348"/>
<source>Up to date</source>
<translation>Up to date</translation>
</message>
<message>
- <location line="+7"/>
+ <location line="+32"/>
<source>Catching up...</source>
<translation>Catching up...</translation>
</message>
<message>
- <location line="+10"/>
- <source>Last received block was generated %1.</source>
- <translation>Last received block was generated %1.</translation>
- </message>
- <message>
- <location line="+97"/>
+ <location line="+110"/>
<source>Confirm transaction fee</source>
<translation>Confirm transaction fee</translation>
</message>
@@ -710,7 +704,7 @@ Address: %4
<translation>There was an error trying to save the wallet data to the new location.</translation>
</message>
<message>
- <location filename="../bitcoin.cpp" line="+110"/>
+ <location filename="../bitcoin.cpp" line="+108"/>
<source>A fatal error occurred. Bitcoin can no longer continue safely and will quit.</source>
<translation>A fatal error occurred. Bitcoin can no longer continue safely and will quit.</translation>
</message>
@@ -718,7 +712,7 @@ Address: %4
<context>
<name>ClientModel</name>
<message>
- <location filename="../clientmodel.cpp" line="+89"/>
+ <location filename="../clientmodel.cpp" line="+96"/>
<source>Network Alert</source>
<translation>Network Alert</translation>
</message>
@@ -751,7 +745,7 @@ Address: %4
<translation>The address associated with this address book entry. This can only be modified for sending addresses.</translation>
</message>
<message>
- <location filename="../editaddressdialog.cpp" line="+20"/>
+ <location filename="../editaddressdialog.cpp" line="+21"/>
<source>New receiving address</source>
<translation>New receiving address</translation>
</message>
@@ -794,7 +788,7 @@ Address: %4
<context>
<name>GUIUtil::HelpMessageBox</name>
<message>
- <location filename="../guiutil.cpp" line="+420"/>
+ <location filename="../guiutil.cpp" line="+422"/>
<location line="+12"/>
<source>Bitcoin-Qt</source>
<translation>Bitcoin-Qt</translation>
@@ -1008,7 +1002,7 @@ Address: %4
<translation>&amp;Apply</translation>
</message>
<message>
- <location filename="../optionsdialog.cpp" line="+55"/>
+ <location filename="../optionsdialog.cpp" line="+53"/>
<source>default</source>
<translation>default</translation>
</message>
@@ -1116,6 +1110,14 @@ Address: %4
</message>
</context>
<context>
+ <name>PaymentServer</name>
+ <message>
+ <location filename="../paymentserver.cpp" line="+107"/>
+ <source>Cannot start bitcoin: click-to-pay handler</source>
+ <translation>Cannot start bitcoin: click-to-pay handler</translation>
+ </message>
+</context>
+<context>
<name>QRCodeDialog</name>
<message>
<location filename="../forms/qrcodedialog.ui" line="+14"/>
@@ -1454,7 +1456,7 @@ Address: %4
</message>
<message>
<location line="+60"/>
- <location filename="../sendcoinsentry.cpp" line="+25"/>
+ <location filename="../sendcoinsentry.cpp" line="+26"/>
<source>Enter a label for this address to add it to your address book</source>
<translation>Enter a label for this address to add it to your address book</translation>
</message>
@@ -1690,7 +1692,7 @@ Address: %4
<context>
<name>TransactionDesc</name>
<message>
- <location filename="../transactiondesc.cpp" line="+19"/>
+ <location filename="../transactiondesc.cpp" line="+20"/>
<source>Open until %1</source>
<translation>Open until %1</translation>
</message>
@@ -1886,7 +1888,7 @@ Address: %4
<context>
<name>TransactionTableModel</name>
<message>
- <location filename="../transactiontablemodel.cpp" line="+226"/>
+ <location filename="../transactiontablemodel.cpp" line="+225"/>
<source>Date</source>
<translation>Date</translation>
</message>
@@ -2010,7 +2012,7 @@ Address: %4
<context>
<name>TransactionView</name>
<message>
- <location filename="../transactionview.cpp" line="+55"/>
+ <location filename="../transactionview.cpp" line="+52"/>
<location line="+16"/>
<source>All</source>
<translation>All</translation>
@@ -2106,7 +2108,7 @@ Address: %4
<translation>Show transaction details</translation>
</message>
<message>
- <location line="+142"/>
+ <location line="+137"/>
<source>Export Transaction Data</source>
<translation>Export Transaction Data</translation>
</message>
@@ -2174,12 +2176,12 @@ Address: %4
<context>
<name>bitcoin-core</name>
<message>
- <location filename="../bitcoinstrings.cpp" line="+90"/>
+ <location filename="../bitcoinstrings.cpp" line="+91"/>
<source>Bitcoin version</source>
<translation>Bitcoin version</translation>
</message>
<message>
- <location line="+96"/>
+ <location line="+99"/>
<source>Usage:</source>
<translation>Usage:</translation>
</message>
@@ -2219,12 +2221,12 @@ Address: %4
<translation>Generate coins</translation>
</message>
<message>
- <location line="-27"/>
+ <location line="-28"/>
<source>Don&apos;t generate coins</source>
<translation>Don&apos;t generate coins</translation>
</message>
<message>
- <location line="+74"/>
+ <location line="+75"/>
<source>Specify data directory</source>
<translation>Specify data directory</translation>
</message>
@@ -2244,12 +2246,12 @@ Address: %4
<translation>Maintain at most &lt;n&gt; connections to peers (default: 125)</translation>
</message>
<message>
- <location line="-47"/>
+ <location line="-50"/>
<source>Connect to a node to retrieve peer addresses, and disconnect</source>
<translation>Connect to a node to retrieve peer addresses, and disconnect</translation>
</message>
<message>
- <location line="+78"/>
+ <location line="+81"/>
<source>Specify your own public address</source>
<translation>Specify your own public address</translation>
</message>
@@ -2259,17 +2261,17 @@ Address: %4
<translation>Threshold for disconnecting misbehaving peers (default: 100)</translation>
</message>
<message>
- <location line="-130"/>
+ <location line="-133"/>
<source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source>
<translation>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</translation>
</message>
<message>
- <location line="-28"/>
+ <location line="-29"/>
<source>An error occurred while setting up the RPC port %u for listening on IPv4: %s</source>
<translation>An error occurred while setting up the RPC port %u for listening on IPv4: %s</translation>
</message>
<message>
- <location line="+26"/>
+ <location line="+27"/>
<source>Listen for JSON-RPC connections on &lt;port&gt; (default: 8332 or testnet: 18332)</source>
<translation>Listen for JSON-RPC connections on &lt;port&gt; (default: 8332 or testnet: 18332)</translation>
</message>
@@ -2279,7 +2281,7 @@ Address: %4
<translation>Accept command line and JSON-RPC commands</translation>
</message>
<message>
- <location line="+75"/>
+ <location line="+78"/>
<source>Run in the background as a daemon and accept commands</source>
<translation>Run in the background as a daemon and accept commands</translation>
</message>
@@ -2289,12 +2291,12 @@ Address: %4
<translation>Use the test network</translation>
</message>
<message>
- <location line="-106"/>
+ <location line="-109"/>
<source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
<translation>Accept connections from outside (default: 1 if no -proxy or -connect)</translation>
</message>
<message>
- <location line="-76"/>
+ <location line="-77"/>
<source>%s, you must set a rpcpassword in the configuration file:
%s
It is recommended you use the following random password:
@@ -2330,11 +2332,6 @@ If the file does not exist, create it with owner-readable-only file permissions.
</message>
<message>
<location line="+3"/>
- <source>Corrupted block database detected. Please restart the client with -reindex.</source>
- <translation>Corrupted block database detected. Please restart the client with -reindex.</translation>
- </message>
- <message>
- <location line="+2"/>
<source>Error initializing database environment %s! To recover, BACKUP THAT DIRECTORY, then remove everything from it except for wallet.dat.</source>
<translation>Error initializing database environment %s! To recover, BACKUP THAT DIRECTORY, then remove everything from it except for wallet.dat.</translation>
</message>
@@ -2349,6 +2346,11 @@ If the file does not exist, create it with owner-readable-only file permissions.
<translation>Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds!</translation>
</message>
<message>
+ <location line="+3"/>
+ <source>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</source>
+ <translation>Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)</translation>
+ </message>
+ <message>
<location line="+11"/>
<source>Set maximum size of high-priority/low-fee transactions in bytes (default: 27000)</source>
<translation>Set maximum size of high-priority/low-fee transactions in bytes (default: 27000)</translation>
@@ -2405,10 +2407,20 @@ If the file does not exist, create it with owner-readable-only file permissions.
</message>
<message>
<location line="+3"/>
+ <source>Corrupted block database detected</source>
+ <translation>Corrupted block database detected</translation>
+ </message>
+ <message>
+ <location line="+1"/>
<source>Discover own IP address (default: 1 when listening and no -externalip)</source>
<translation>Discover own IP address (default: 1 when listening and no -externalip)</translation>
</message>
<message>
+ <location line="+1"/>
+ <source>Do you want to rebuild the block database now?</source>
+ <translation>Do you want to rebuild the block database now?</translation>
+ </message>
+ <message>
<location line="+3"/>
<source>Error initializing block database</source>
<translation>Error initializing block database</translation>
@@ -2419,7 +2431,12 @@ If the file does not exist, create it with owner-readable-only file permissions.
<translation>Error loading block database</translation>
</message>
<message>
- <location line="+5"/>
+ <location line="+4"/>
+ <source>Error opening block database</source>
+ <translation>Error opening block database</translation>
+ </message>
+ <message>
+ <location line="+2"/>
<source>Error: Disk space is low!</source>
<translation>Error: Disk space is low!</translation>
</message>
@@ -2639,7 +2656,12 @@ If the file does not exist, create it with owner-readable-only file permissions.
<translation>Username for JSON-RPC connections</translation>
</message>
<message>
- <location line="+4"/>
+ <location line="+1"/>
+ <source>Verifying database...</source>
+ <translation>Verifying database...</translation>
+ </message>
+ <message>
+ <location line="+3"/>
<source>Warning</source>
<translation>Warning</translation>
</message>
@@ -2664,22 +2686,22 @@ If the file does not exist, create it with owner-readable-only file permissions.
<translation>Password for JSON-RPC connections</translation>
</message>
<message>
- <location line="-66"/>
+ <location line="-69"/>
<source>Allow JSON-RPC connections from specified IP address</source>
<translation>Allow JSON-RPC connections from specified IP address</translation>
</message>
<message>
- <location line="+75"/>
+ <location line="+78"/>
<source>Send commands to node running on &lt;ip&gt; (default: 127.0.0.1)</source>
<translation>Send commands to node running on &lt;ip&gt; (default: 127.0.0.1)</translation>
</message>
<message>
- <location line="-118"/>
+ <location line="-121"/>
<source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
<translation>Execute command when the best block changes (%s in cmd is replaced by block hash)</translation>
</message>
<message>
- <location line="+140"/>
+ <location line="+143"/>
<source>Upgrade wallet to latest format</source>
<translation>Upgrade wallet to latest format</translation>
</message>
@@ -2709,12 +2731,12 @@ If the file does not exist, create it with owner-readable-only file permissions.
<translation>Server private key (default: server.pem)</translation>
</message>
<message>
- <location line="-148"/>
+ <location line="-152"/>
<source>Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)</source>
<translation>Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)</translation>
</message>
<message>
- <location line="+160"/>
+ <location line="+164"/>
<source>This help message</source>
<translation>This help message</translation>
</message>
@@ -2724,7 +2746,7 @@ If the file does not exist, create it with owner-readable-only file permissions.
<translation>Unable to bind to %s on this computer (bind returned error %d, %s)</translation>
</message>
<message>
- <location line="-84"/>
+ <location line="-87"/>
<source>Connect through socks proxy</source>
<translation>Connect through socks proxy</translation>
</message>
@@ -2734,12 +2756,12 @@ If the file does not exist, create it with owner-readable-only file permissions.
<translation>Allow DNS lookups for -addnode, -seednode and -connect</translation>
</message>
<message>
- <location line="+55"/>
+ <location line="+58"/>
<source>Loading addresses...</source>
<translation>Loading addresses...</translation>
</message>
<message>
- <location line="-36"/>
+ <location line="-37"/>
<source>Error loading wallet.dat: Wallet corrupted</source>
<translation>Error loading wallet.dat: Wallet corrupted</translation>
</message>
@@ -2749,12 +2771,7 @@ If the file does not exist, create it with owner-readable-only file permissions.
<translation>Error loading wallet.dat: Wallet requires newer version of Bitcoin</translation>
</message>
<message>
- <location line="+86"/>
- <source>Verifying block database integrity...</source>
- <translation>Verifying block database integrity...</translation>
- </message>
- <message>
- <location line="+1"/>
+ <location line="+88"/>
<source>Verifying wallet integrity...</source>
<translation>Verifying wallet integrity...</translation>
</message>
@@ -2764,12 +2781,12 @@ If the file does not exist, create it with owner-readable-only file permissions.
<translation>Wallet needed to be rewritten: restart Bitcoin to complete</translation>
</message>
<message>
- <location line="-90"/>
+ <location line="-91"/>
<source>Error loading wallet.dat</source>
<translation>Error loading wallet.dat</translation>
</message>
<message>
- <location line="+31"/>
+ <location line="+32"/>
<source>Invalid -proxy address: &apos;%s&apos;</source>
<translation>Invalid -proxy address: &apos;%s&apos;</translation>
</message>
@@ -2784,7 +2801,7 @@ If the file does not exist, create it with owner-readable-only file permissions.
<translation>Unknown -socks proxy version requested: %i</translation>
</message>
<message>
- <location line="-89"/>
+ <location line="-92"/>
<source>Cannot resolve -bind address: &apos;%s&apos;</source>
<translation>Cannot resolve -bind address: &apos;%s&apos;</translation>
</message>
@@ -2794,7 +2811,7 @@ If the file does not exist, create it with owner-readable-only file permissions.
<translation>Cannot resolve -externalip address: &apos;%s&apos;</translation>
</message>
<message>
- <location line="+43"/>
+ <location line="+46"/>
<source>Invalid amount for -paytxfee=&lt;amount&gt;: &apos;%s&apos;</source>
<translation>Invalid amount for -paytxfee=&lt;amount&gt;: &apos;%s&apos;</translation>
</message>
@@ -2819,7 +2836,7 @@ If the file does not exist, create it with owner-readable-only file permissions.
<translation>Loading block index...</translation>
</message>
<message>
- <location line="-57"/>
+ <location line="-60"/>
<source>Add a node to connect to and attempt to keep the connection open</source>
<translation>Add a node to connect to and attempt to keep the connection open</translation>
</message>
@@ -2829,7 +2846,7 @@ If the file does not exist, create it with owner-readable-only file permissions.
<translation>Unable to bind to %s on this computer. Bitcoin is probably already running.</translation>
</message>
<message>
- <location line="+66"/>
+ <location line="+69"/>
<source>Find peers using internet relay chat (default: 0)</source>
<translation>Find peers using internet relay chat (default: 0)</translation>
</message>
@@ -2844,7 +2861,7 @@ If the file does not exist, create it with owner-readable-only file permissions.
<translation>Loading wallet...</translation>
</message>
<message>
- <location line="-52"/>
+ <location line="-55"/>
<source>Cannot downgrade wallet</source>
<translation>Cannot downgrade wallet</translation>
</message>
@@ -2859,17 +2876,17 @@ If the file does not exist, create it with owner-readable-only file permissions.
<translation>Cannot write default address</translation>
</message>
<message>
- <location line="+62"/>
+ <location line="+65"/>
<source>Rescanning...</source>
<translation>Rescanning...</translation>
</message>
<message>
- <location line="-56"/>
+ <location line="-57"/>
<source>Done loading</source>
<translation>Done loading</translation>
</message>
<message>
- <location line="+79"/>
+ <location line="+80"/>
<source>To use the %s option</source>
<translation>To use the %s option</translation>
</message>
@@ -2879,7 +2896,7 @@ If the file does not exist, create it with owner-readable-only file permissions.
<translation>Error</translation>
</message>
<message>
- <location line="-29"/>
+ <location line="-32"/>
<source>You must set rpcpassword=&lt;password&gt; in the configuration file:
%s
If the file does not exist, create it with owner-readable-only file permissions.</source>
diff --git a/src/qt/res/bitcoin-qt.rc b/src/qt/res/bitcoin-qt.rc
index 834001c0c6..5449ff8359 100644
--- a/src/qt/res/bitcoin-qt.rc
+++ b/src/qt/res/bitcoin-qt.rc
@@ -22,7 +22,7 @@ BEGIN
VALUE "FileDescription", "Bitcoin-Qt (OSS GUI client for Bitcoin)"
VALUE "FileVersion", VER_FILEVERSION_STR
VALUE "InternalName", "bitcoin-qt"
- VALUE "LegalCopyright", "2009-2012 The Bitcoin developers"
+ VALUE "LegalCopyright", "2009-2013 The Bitcoin developers"
VALUE "LegalTrademarks1", "Distributed under the MIT/X11 software license, see the accompanying file COPYING or http://www.opensource.org/licenses/mit-license.php."
VALUE "OriginalFilename", "bitcoin-qt.exe"
VALUE "ProductName", "Bitcoin-Qt"
diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp
index 56392f96dd..2133a5e729 100644
--- a/src/qt/sendcoinsdialog.cpp
+++ b/src/qt/sendcoinsdialog.cpp
@@ -245,6 +245,26 @@ QWidget *SendCoinsDialog::setupTabChain(QWidget *prev)
return ui->sendButton;
}
+void SendCoinsDialog::setAddress(const QString &address)
+{
+ SendCoinsEntry *entry = 0;
+ // Replace the first entry if it is still unused
+ if(ui->entries->count() == 1)
+ {
+ SendCoinsEntry *first = qobject_cast<SendCoinsEntry*>(ui->entries->itemAt(0)->widget());
+ if(first->isClear())
+ {
+ entry = first;
+ }
+ }
+ if(!entry)
+ {
+ entry = addEntry();
+ }
+
+ entry->setAddress(address);
+}
+
void SendCoinsDialog::pasteEntry(const SendCoinsRecipient &rv)
{
if(!fNewRecipientAllowed)
diff --git a/src/qt/sendcoinsdialog.h b/src/qt/sendcoinsdialog.h
index 8a6e050c11..043dfdcb40 100644
--- a/src/qt/sendcoinsdialog.h
+++ b/src/qt/sendcoinsdialog.h
@@ -29,6 +29,7 @@ public:
*/
QWidget *setupTabChain(QWidget *prev);
+ void setAddress(const QString &address);
void pasteEntry(const SendCoinsRecipient &rv);
bool handleURI(const QString &uri);
diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp
index 7dbca24084..876b7f808b 100644
--- a/src/qt/sendcoinsentry.cpp
+++ b/src/qt/sendcoinsentry.cpp
@@ -153,6 +153,12 @@ void SendCoinsEntry::setValue(const SendCoinsRecipient &value)
ui->payAmount->setValue(value.amount);
}
+void SendCoinsEntry::setAddress(const QString &address)
+{
+ ui->payTo->setText(address);
+ ui->payAmount->setFocus();
+}
+
bool SendCoinsEntry::isClear()
{
return ui->payTo->text().isEmpty();
diff --git a/src/qt/sendcoinsentry.h b/src/qt/sendcoinsentry.h
index 0ac14c1472..ec5f3410c1 100644
--- a/src/qt/sendcoinsentry.h
+++ b/src/qt/sendcoinsentry.h
@@ -26,6 +26,7 @@ public:
bool isClear();
void setValue(const SendCoinsRecipient &value);
+ void setAddress(const QString &address);
/** Set up the tab chain manually, as Qt messes up the tab chain by default in some cases (issue https://bugreports.qt-project.org/browse/QTBUG-10907).
*/
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..a53aa65466
--- /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()
+{
+ 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();
+}
diff --git a/src/qt/walletframe.h b/src/qt/walletframe.h
new file mode 100644
index 0000000000..5b4baf7255
--- /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();
+
+ /** 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/walletstack.cpp b/src/qt/walletstack.cpp
new file mode 100644
index 0000000000..271d1c7924
--- /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()
+{
+ 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();
+}
diff --git a/src/qt/walletstack.h b/src/qt/walletstack.h
new file mode 100644
index 0000000000..f3485816e9
--- /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();
+
+ /** 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..7dd36234c9
--- /dev/null
+++ b/src/qt/walletview.cpp
@@ -0,0 +1,354 @@
+/*
+ * Qt4 bitcoin GUI.
+ *
+ * W.J. van der Laan 2011-2012
+ * The Bitcoin Developers 2011-2013
+ */
+#include "walletview.h"
+#include "bitcoingui.h"
+#include "transactiontablemodel.h"
+#include "addressbookpage.h"
+#include "sendcoinsdialog.h"
+#include "signverifymessagedialog.h"
+#include "optionsdialog.h"
+#include "aboutdialog.h"
+#include "clientmodel.h"
+#include "walletmodel.h"
+#include "editaddressdialog.h"
+#include "optionsmodel.h"
+#include "transactiondescdialog.h"
+#include "addresstablemodel.h"
+#include "transactionview.h"
+#include "overviewpage.h"
+#include "bitcoinunits.h"
+#include "guiconstants.h"
+#include "askpassphrasedialog.h"
+#include "guiutil.h"
+#include "ui_interface.h"
+
+#include <QVBoxLayout>
+#include <QActionGroup>
+#include <QAction>
+#include <QLabel>
+#include <QDesktopServices>
+#include <QFileDialog>
+
+WalletView::WalletView(QWidget *parent, BitcoinGUI *_gui):
+ QStackedWidget(parent),
+ gui(_gui),
+ clientModel(0),
+ walletModel(0),
+ encryptWalletAction(0),
+ changePassphraseAction(0)
+{
+ // Create actions for the toolbar, menu bar and tray/dock icon
+ createActions();
+
+ // Create tabs
+ overviewPage = new OverviewPage();
+
+ transactionsPage = new QWidget(this);
+ QVBoxLayout *vbox = new QVBoxLayout();
+ transactionView = new TransactionView(this);
+ vbox->addWidget(transactionView);
+ transactionsPage->setLayout(vbox);
+
+ addressBookPage = new AddressBookPage(AddressBookPage::ForEditing, AddressBookPage::SendingTab);
+
+ receiveCoinsPage = new AddressBookPage(AddressBookPage::ForEditing, AddressBookPage::ReceivingTab);
+
+ sendCoinsPage = new SendCoinsDialog(gui);
+
+ signVerifyMessageDialog = new SignVerifyMessageDialog(gui);
+
+ addWidget(overviewPage);
+ addWidget(transactionsPage);
+ addWidget(addressBookPage);
+ addWidget(receiveCoinsPage);
+ addWidget(sendCoinsPage);
+
+ // Clicking on a transaction on the overview page simply sends you to transaction history page
+ connect(overviewPage, SIGNAL(transactionClicked(QModelIndex)), this, SLOT(gotoHistoryPage()));
+ connect(overviewPage, SIGNAL(transactionClicked(QModelIndex)), transactionView, SLOT(focusTransaction(QModelIndex)));
+
+ // Double-clicking on a transaction on the transaction history page shows details
+ connect(transactionView, SIGNAL(doubleClicked(QModelIndex)), transactionView, SLOT(showDetails()));
+
+ // Clicking on "Verify Message" in the address book sends you to the verify message tab
+ connect(addressBookPage, SIGNAL(verifyMessage(QString)), this, SLOT(gotoVerifyMessageTab(QString)));
+ // Clicking on "Sign Message" in the receive coins page sends you to the sign message tab
+ connect(receiveCoinsPage, SIGNAL(signMessage(QString)), this, SLOT(gotoSignMessageTab(QString)));
+
+ gotoOverviewPage();
+}
+
+WalletView::~WalletView()
+{
+}
+
+void WalletView::createActions()
+{
+ QActionGroup *tabGroup = new QActionGroup(this);
+
+ overviewAction = new QAction(QIcon(":/icons/overview"), tr("&Overview"), this);
+ overviewAction->setStatusTip(tr("Show general overview of wallet"));
+ overviewAction->setToolTip(overviewAction->statusTip());
+ overviewAction->setCheckable(true);
+ overviewAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_1));
+ tabGroup->addAction(overviewAction);
+
+ sendCoinsAction = new QAction(QIcon(":/icons/send"), tr("&Send coins"), this);
+ sendCoinsAction->setStatusTip(tr("Send coins to a Bitcoin address"));
+ sendCoinsAction->setToolTip(sendCoinsAction->statusTip());
+ sendCoinsAction->setCheckable(true);
+ sendCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_2));
+ tabGroup->addAction(sendCoinsAction);
+
+ receiveCoinsAction = new QAction(QIcon(":/icons/receiving_addresses"), tr("&Receive coins"), this);
+ receiveCoinsAction->setStatusTip(tr("Show the list of addresses for receiving payments"));
+ receiveCoinsAction->setToolTip(receiveCoinsAction->statusTip());
+ receiveCoinsAction->setCheckable(true);
+ receiveCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_3));
+ tabGroup->addAction(receiveCoinsAction);
+
+ historyAction = new QAction(QIcon(":/icons/history"), tr("&Transactions"), this);
+ historyAction->setStatusTip(tr("Browse transaction history"));
+ historyAction->setToolTip(historyAction->statusTip());
+ historyAction->setCheckable(true);
+ historyAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_4));
+ tabGroup->addAction(historyAction);
+
+ addressBookAction = new QAction(QIcon(":/icons/address-book"), tr("&Address Book"), this);
+ addressBookAction->setStatusTip(tr("Edit the list of stored addresses and labels"));
+ addressBookAction->setToolTip(addressBookAction->statusTip());
+ addressBookAction->setCheckable(true);
+ addressBookAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_5));
+ tabGroup->addAction(addressBookAction);
+
+ connect(overviewAction, SIGNAL(triggered()), this, SLOT(gotoOverviewPage()));
+ connect(sendCoinsAction, SIGNAL(triggered()), this, SLOT(gotoSendCoinsPage()));
+ connect(receiveCoinsAction, SIGNAL(triggered()), this, SLOT(gotoReceiveCoinsPage()));
+ connect(historyAction, SIGNAL(triggered()), this, SLOT(gotoHistoryPage()));
+ connect(addressBookAction, SIGNAL(triggered()), this, SLOT(gotoAddressBookPage()));
+
+ encryptWalletAction = new QAction(QIcon(":/icons/lock_closed"), tr("&Encrypt Wallet..."), this);
+ encryptWalletAction->setStatusTip(tr("Encrypt the private keys that belong to your wallet"));
+ encryptWalletAction->setCheckable(true);
+ backupWalletAction = new QAction(QIcon(":/icons/filesave"), tr("&Backup Wallet..."), this);
+ backupWalletAction->setStatusTip(tr("Backup wallet to another location"));
+ changePassphraseAction = new QAction(QIcon(":/icons/key"), tr("&Change Passphrase..."), this);
+ changePassphraseAction->setStatusTip(tr("Change the passphrase used for wallet encryption"));
+ signMessageAction = new QAction(QIcon(":/icons/edit"), tr("Sign &message..."), this);
+ signMessageAction->setStatusTip(tr("Sign messages with your Bitcoin addresses to prove you own them"));
+ verifyMessageAction = new QAction(QIcon(":/icons/transaction_0"), tr("&Verify message..."), this);
+ verifyMessageAction->setStatusTip(tr("Verify messages to ensure they were signed with specified Bitcoin addresses"));
+
+ exportAction = new QAction(QIcon(":/icons/export"), tr("&Export..."), this);
+ exportAction->setStatusTip(tr("Export the data in the current tab to a file"));
+ exportAction->setToolTip(exportAction->statusTip());
+
+ connect(encryptWalletAction, SIGNAL(triggered(bool)), this, SLOT(encryptWallet(bool)));
+ connect(backupWalletAction, SIGNAL(triggered()), this, SLOT(backupWallet()));
+ connect(changePassphraseAction, SIGNAL(triggered()), this, SLOT(changePassphrase()));
+ connect(signMessageAction, SIGNAL(triggered()), this, SLOT(gotoSignMessageTab()));
+ connect(verifyMessageAction, SIGNAL(triggered()), this, SLOT(gotoVerifyMessageTab()));
+}
+
+void WalletView::setBitcoinGUI(BitcoinGUI *gui)
+{
+ this->gui = gui;
+}
+
+void WalletView::setClientModel(ClientModel *clientModel)
+{
+ this->clientModel = clientModel;
+ if(clientModel)
+ {
+ overviewPage->setClientModel(clientModel);
+ addressBookPage->setOptionsModel(clientModel->getOptionsModel());
+ receiveCoinsPage->setOptionsModel(clientModel->getOptionsModel());
+ }
+}
+
+void WalletView::setWalletModel(WalletModel *walletModel)
+{
+ this->walletModel = walletModel;
+ if(walletModel)
+ {
+ // Receive and report messages from wallet thread
+ connect(walletModel, SIGNAL(message(QString,QString,unsigned int)), gui, SLOT(message(QString,QString,unsigned int)));
+
+ // Put transaction list in tabs
+ transactionView->setModel(walletModel);
+ overviewPage->setWalletModel(walletModel);
+ addressBookPage->setModel(walletModel->getAddressTableModel());
+ receiveCoinsPage->setModel(walletModel->getAddressTableModel());
+ sendCoinsPage->setModel(walletModel);
+ signVerifyMessageDialog->setModel(walletModel);
+
+ setEncryptionStatus();
+ connect(walletModel, SIGNAL(encryptionStatusChanged(int)), gui, SLOT(setEncryptionStatus(int)));
+
+ // Balloon pop-up for new transaction
+ connect(walletModel->getTransactionTableModel(), SIGNAL(rowsInserted(QModelIndex,int,int)),
+ this, SLOT(incomingTransaction(QModelIndex,int,int)));
+
+ // Ask for passphrase if needed
+ connect(walletModel, SIGNAL(requireUnlock()), this, SLOT(unlockWallet()));
+ }
+}
+
+void WalletView::incomingTransaction(const QModelIndex& parent, int start, int /*end*/)
+{
+ // Prevent balloon-spam when initial block download is in progress
+ if(!walletModel || !clientModel || clientModel->inInitialBlockDownload())
+ return;
+
+ TransactionTableModel *ttm = walletModel->getTransactionTableModel();
+
+ QString date = ttm->index(start, TransactionTableModel::Date, parent)
+ .data().toString();
+ qint64 amount = ttm->index(start, TransactionTableModel::Amount, parent)
+ .data(Qt::EditRole).toULongLong();
+ QString type = ttm->index(start, TransactionTableModel::Type, parent)
+ .data().toString();
+ QString address = ttm->index(start, TransactionTableModel::ToAddress, parent)
+ .data().toString();
+
+ gui->incomingTransaction(date, walletModel->getOptionsModel()->getDisplayUnit(), amount, type, address);
+}
+
+void WalletView::gotoOverviewPage()
+{
+ overviewAction->setChecked(true);
+ setCurrentWidget(overviewPage);
+
+ exportAction->setEnabled(false);
+ disconnect(exportAction, SIGNAL(triggered()), 0, 0);
+}
+
+void WalletView::gotoHistoryPage()
+{
+ historyAction->setChecked(true);
+ setCurrentWidget(transactionsPage);
+
+ exportAction->setEnabled(true);
+ disconnect(exportAction, SIGNAL(triggered()), 0, 0);
+ connect(exportAction, SIGNAL(triggered()), transactionView, SLOT(exportClicked()));
+}
+
+void WalletView::gotoAddressBookPage()
+{
+ addressBookAction->setChecked(true);
+ setCurrentWidget(addressBookPage);
+
+ exportAction->setEnabled(true);
+ disconnect(exportAction, SIGNAL(triggered()), 0, 0);
+ connect(exportAction, SIGNAL(triggered()), addressBookPage, SLOT(exportClicked()));
+}
+
+void WalletView::gotoReceiveCoinsPage()
+{
+ receiveCoinsAction->setChecked(true);
+ setCurrentWidget(receiveCoinsPage);
+
+ exportAction->setEnabled(true);
+ disconnect(exportAction, SIGNAL(triggered()), 0, 0);
+ connect(exportAction, SIGNAL(triggered()), receiveCoinsPage, SLOT(exportClicked()));
+}
+
+void WalletView::gotoSendCoinsPage()
+{
+ sendCoinsAction->setChecked(true);
+ setCurrentWidget(sendCoinsPage);
+
+ exportAction->setEnabled(false);
+ disconnect(exportAction, SIGNAL(triggered()), 0, 0);
+}
+
+void WalletView::gotoSignMessageTab(QString addr)
+{
+ // call show() in showTab_SM()
+ signVerifyMessageDialog->showTab_SM(true);
+
+ if(!addr.isEmpty())
+ signVerifyMessageDialog->setAddress_SM(addr);
+}
+
+void WalletView::gotoVerifyMessageTab(QString addr)
+{
+ // call show() in showTab_VM()
+ signVerifyMessageDialog->showTab_VM(true);
+
+ if(!addr.isEmpty())
+ signVerifyMessageDialog->setAddress_VM(addr);
+}
+
+bool WalletView::handleURI(const QString& strURI)
+{
+ // URI has to be valid
+ if (sendCoinsPage->handleURI(strURI))
+ {
+ gotoSendCoinsPage();
+ return true;
+ }
+ else
+ return false;
+}
+
+void WalletView::showOutOfSyncWarning(bool fShow)
+{
+ overviewPage->showOutOfSyncWarning(fShow);
+}
+
+void WalletView::setEncryptionStatus()
+{
+ gui->setEncryptionStatus(walletModel->getEncryptionStatus());
+}
+
+void WalletView::encryptWallet(bool status)
+{
+ if(!walletModel)
+ return;
+ AskPassphraseDialog dlg(status ? AskPassphraseDialog::Encrypt:
+ AskPassphraseDialog::Decrypt, this);
+ dlg.setModel(walletModel);
+ dlg.exec();
+
+ setEncryptionStatus();
+}
+
+void WalletView::backupWallet()
+{
+ QString saveDir = QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation);
+ QString filename = QFileDialog::getSaveFileName(this, tr("Backup Wallet"), saveDir, tr("Wallet Data (*.dat)"));
+ if(!filename.isEmpty()) {
+ if(!walletModel->backupWallet(filename)) {
+ gui->message(tr("Backup Failed"), tr("There was an error trying to save the wallet data to the new location."),
+ CClientUIInterface::MSG_ERROR);
+ }
+ else
+ gui->message(tr("Backup Successful"), tr("The wallet data was successfully saved to the new location."),
+ CClientUIInterface::MSG_INFORMATION);
+ }
+}
+
+void WalletView::changePassphrase()
+{
+ AskPassphraseDialog dlg(AskPassphraseDialog::ChangePass, this);
+ dlg.setModel(walletModel);
+ dlg.exec();
+}
+
+void WalletView::unlockWallet()
+{
+ if(!walletModel)
+ return;
+ // Unlock wallet when requested by wallet model
+ if(walletModel->getEncryptionStatus() == WalletModel::Locked)
+ {
+ AskPassphraseDialog dlg(AskPassphraseDialog::Unlock, this);
+ dlg.setModel(walletModel);
+ dlg.exec();
+ }
+}
diff --git a/src/qt/walletview.h b/src/qt/walletview.h
new file mode 100644
index 0000000000..38eb0227af
--- /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();
+
+ /** 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