aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/qt/Makefile.am2
-rw-r--r--src/qt/bitcoingui.cpp14
-rw-r--r--src/qt/bitcoingui.h3
-rw-r--r--src/qt/forms/askpassphrasedialog.ui16
-rw-r--r--src/qt/forms/editaddressdialog.ui16
-rw-r--r--src/qt/forms/intro.ui16
-rw-r--r--src/qt/forms/receivecoinsdialog.ui6
-rw-r--r--src/qt/forms/rpcconsole.ui26
-rw-r--r--src/qt/forms/sendcoinsentry.ui17
-rw-r--r--src/qt/forms/signverifymessagedialog.ui3
-rw-r--r--src/qt/forms/transactiondescdialog.ui16
-rw-r--r--src/qt/optionsdialog.cpp3
-rw-r--r--src/qt/optionsmodel.cpp24
-rw-r--r--src/qt/optionsmodel.h6
-rw-r--r--src/qt/paymentserver.cpp25
-rw-r--r--src/qt/receivecoinsdialog.cpp2
-rw-r--r--src/qt/recentrequeststablemodel.cpp78
-rw-r--r--src/qt/recentrequeststablemodel.h45
-rw-r--r--src/qt/rpcconsole.cpp8
-rw-r--r--src/qt/rpcconsole.h2
-rw-r--r--src/qt/sendcoinsentry.cpp9
-rw-r--r--src/qt/splashscreen.cpp2
-rw-r--r--src/qt/transactiondesc.cpp5
-rw-r--r--src/qt/walletmodel.cpp26
-rw-r--r--src/qt/walletmodel.h42
-rw-r--r--src/rpcdump.cpp5
-rw-r--r--src/wallet.cpp54
-rw-r--r--src/wallet.h12
-rw-r--r--src/walletdb.cpp24
-rw-r--r--src/walletdb.h5
30 files changed, 413 insertions, 99 deletions
diff --git a/src/qt/Makefile.am b/src/qt/Makefile.am
index 3dfe8ee6ca..cac6039663 100644
--- a/src/qt/Makefile.am
+++ b/src/qt/Makefile.am
@@ -133,7 +133,7 @@ QT_MOC_CPP = \
moc_transactionfilterproxy.cpp \
moc_transactiontablemodel.cpp \
moc_transactionview.cpp \
- moc_utilitydialog.cpp \
+ moc_utilitydialog.cpp \
moc_walletframe.cpp \
moc_walletmodel.cpp \
moc_walletview.cpp
diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
index 1008ef2b08..f548c65161 100644
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -308,11 +308,15 @@ void BitcoinGUI::createActions(bool fIsTestnet)
openAction = new QAction(QApplication::style()->standardIcon(QStyle::SP_FileIcon), tr("Open &URI..."), this);
openAction->setStatusTip(tr("Open a bitcoin: URI or payment request"));
+ showHelpMessageAction = new QAction(QApplication::style()->standardIcon(QStyle::SP_MessageBoxInformation), tr("&Command-line options"), this);
+ showHelpMessageAction->setStatusTip(tr("Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options"));
+
connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
connect(aboutAction, SIGNAL(triggered()), this, SLOT(aboutClicked()));
connect(aboutQtAction, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
connect(optionsAction, SIGNAL(triggered()), this, SLOT(optionsClicked()));
connect(toggleHideAction, SIGNAL(triggered()), this, SLOT(toggleHidden()));
+ connect(showHelpMessageAction, SIGNAL(triggered()), this, SLOT(showHelpMessageClicked()));
#ifdef ENABLE_WALLET
if(walletFrame)
{
@@ -366,8 +370,9 @@ void BitcoinGUI::createMenuBar()
if(walletFrame)
{
help->addAction(openRPCConsoleAction);
- help->addSeparator();
}
+ help->addAction(showHelpMessageAction);
+ help->addSeparator();
help->addAction(aboutAction);
help->addAction(aboutQtAction);
}
@@ -546,6 +551,13 @@ void BitcoinGUI::aboutClicked()
dlg.exec();
}
+void BitcoinGUI::showHelpMessageClicked()
+{
+ HelpMessageDialog *help = new HelpMessageDialog(this);
+ help->setAttribute(Qt::WA_DeleteOnClose);
+ help->show();
+}
+
#ifdef ENABLE_WALLET
void BitcoinGUI::openClicked()
{
diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h
index d5bbdca484..4dce4431ba 100644
--- a/src/qt/bitcoingui.h
+++ b/src/qt/bitcoingui.h
@@ -93,6 +93,7 @@ private:
QAction *aboutQtAction;
QAction *openRPCConsoleAction;
QAction *openAction;
+ QAction *showHelpMessageAction;
QSystemTrayIcon *trayIcon;
Notificator *notificator;
@@ -176,6 +177,8 @@ private slots:
void optionsClicked();
/** Show about dialog */
void aboutClicked();
+ /** Show help message dialog */
+ void showHelpMessageClicked();
#ifndef Q_OS_MAC
/** Handle tray icon clicked */
void trayIconActivated(QSystemTrayIcon::ActivationReason reason);
diff --git a/src/qt/forms/askpassphrasedialog.ui b/src/qt/forms/askpassphrasedialog.ui
index 25169042a1..bc4921455f 100644
--- a/src/qt/forms/askpassphrasedialog.ui
+++ b/src/qt/forms/askpassphrasedialog.ui
@@ -122,12 +122,12 @@
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
- <x>248</x>
- <y>254</y>
+ <x>20</x>
+ <y>20</y>
</hint>
<hint type="destinationlabel">
- <x>157</x>
- <y>274</y>
+ <x>20</x>
+ <y>20</y>
</hint>
</hints>
</connection>
@@ -138,12 +138,12 @@
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
- <x>316</x>
- <y>260</y>
+ <x>20</x>
+ <y>20</y>
</hint>
<hint type="destinationlabel">
- <x>286</x>
- <y>274</y>
+ <x>20</x>
+ <y>20</y>
</hint>
</hints>
</connection>
diff --git a/src/qt/forms/editaddressdialog.ui b/src/qt/forms/editaddressdialog.ui
index 8ff3805226..915b3679a1 100644
--- a/src/qt/forms/editaddressdialog.ui
+++ b/src/qt/forms/editaddressdialog.ui
@@ -76,12 +76,12 @@
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
- <x>248</x>
- <y>254</y>
+ <x>20</x>
+ <y>20</y>
</hint>
<hint type="destinationlabel">
- <x>157</x>
- <y>274</y>
+ <x>20</x>
+ <y>20</y>
</hint>
</hints>
</connection>
@@ -92,12 +92,12 @@
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
- <x>316</x>
- <y>260</y>
+ <x>20</x>
+ <y>20</y>
</hint>
<hint type="destinationlabel">
- <x>286</x>
- <y>274</y>
+ <x>20</x>
+ <y>20</y>
</hint>
</hints>
</connection>
diff --git a/src/qt/forms/intro.ui b/src/qt/forms/intro.ui
index 05ee9466c4..09e7bdb024 100644
--- a/src/qt/forms/intro.ui
+++ b/src/qt/forms/intro.ui
@@ -237,12 +237,12 @@
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
- <x>248</x>
- <y>254</y>
+ <x>20</x>
+ <y>20</y>
</hint>
<hint type="destinationlabel">
- <x>157</x>
- <y>274</y>
+ <x>20</x>
+ <y>20</y>
</hint>
</hints>
</connection>
@@ -253,12 +253,12 @@
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
- <x>316</x>
- <y>260</y>
+ <x>20</x>
+ <y>20</y>
</hint>
<hint type="destinationlabel">
- <x>286</x>
- <y>274</y>
+ <x>20</x>
+ <y>20</y>
</hint>
</hints>
</connection>
diff --git a/src/qt/forms/receivecoinsdialog.ui b/src/qt/forms/receivecoinsdialog.ui
index 8242763e77..7bf01224ee 100644
--- a/src/qt/forms/receivecoinsdialog.ui
+++ b/src/qt/forms/receivecoinsdialog.ui
@@ -207,7 +207,11 @@
</widget>
</item>
<item>
- <widget class="QTableView" name="recentRequestsView"/>
+ <widget class="QTableView" name="recentRequestsView">
+ <property name="sortingEnabled">
+ <bool>true</bool>
+ </property>
+ </widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
diff --git a/src/qt/forms/rpcconsole.ui b/src/qt/forms/rpcconsole.ui
index 69504f3159..31d61ec468 100644
--- a/src/qt/forms/rpcconsole.ui
+++ b/src/qt/forms/rpcconsole.ui
@@ -339,32 +339,6 @@
</widget>
</item>
<item row="16" column="0">
- <widget class="QLabel" name="labelCLOptions">
- <property name="font">
- <font>
- <weight>75</weight>
- <bold>true</bold>
- </font>
- </property>
- <property name="text">
- <string>Command-line options</string>
- </property>
- </widget>
- </item>
- <item row="17" column="0">
- <widget class="QPushButton" name="showCLOptionsButton">
- <property name="toolTip">
- <string>Show the Bitcoin-Core help message to get a list with possible Bitcoin command-line options.</string>
- </property>
- <property name="text">
- <string>&amp;Show</string>
- </property>
- <property name="autoDefault">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="18" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
diff --git a/src/qt/forms/sendcoinsentry.ui b/src/qt/forms/sendcoinsentry.ui
index b6cec5baf0..96c922af4d 100644
--- a/src/qt/forms/sendcoinsentry.ui
+++ b/src/qt/forms/sendcoinsentry.ui
@@ -141,6 +141,23 @@
<item row="2" column="1">
<widget class="BitcoinAmountField" name="payAmount"/>
</item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="messageLabel">
+ <property name="text">
+ <string>Message:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QLabel" name="messageTextLabel">
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
<widget class="QFrame" name="SendCoins_InsecurePaymentRequest">
diff --git a/src/qt/forms/signverifymessagedialog.ui b/src/qt/forms/signverifymessagedialog.ui
index 04d614a1cd..989522bb58 100644
--- a/src/qt/forms/signverifymessagedialog.ui
+++ b/src/qt/forms/signverifymessagedialog.ui
@@ -19,9 +19,6 @@
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QTabWidget" name="tabWidget">
- <property name="currentIndex">
- <number>0</number>
- </property>
<widget class="QWidget" name="tabSignMessage">
<attribute name="title">
<string>&amp;Sign Message</string>
diff --git a/src/qt/forms/transactiondescdialog.ui b/src/qt/forms/transactiondescdialog.ui
index b38dffcc12..5ae1e12856 100644
--- a/src/qt/forms/transactiondescdialog.ui
+++ b/src/qt/forms/transactiondescdialog.ui
@@ -45,12 +45,12 @@
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
- <x>248</x>
- <y>254</y>
+ <x>20</x>
+ <y>20</y>
</hint>
<hint type="destinationlabel">
- <x>157</x>
- <y>274</y>
+ <x>20</x>
+ <y>20</y>
</hint>
</hints>
</connection>
@@ -61,12 +61,12 @@
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
- <x>316</x>
- <y>260</y>
+ <x>20</x>
+ <y>20</y>
</hint>
<hint type="destinationlabel">
- <x>286</x>
- <y>274</y>
+ <x>20</x>
+ <y>20</y>
</hint>
</hints>
</connection>
diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp
index d024e3b7aa..f61bb3ed2c 100644
--- a/src/qt/optionsdialog.cpp
+++ b/src/qt/optionsdialog.cpp
@@ -53,7 +53,6 @@ OptionsDialog::OptionsDialog(QWidget *parent) :
connect(ui->connectSocks, SIGNAL(toggled(bool)), ui->proxyIp, SLOT(setEnabled(bool)));
connect(ui->connectSocks, SIGNAL(toggled(bool)), ui->proxyPort, SLOT(setEnabled(bool)));
connect(ui->connectSocks, SIGNAL(toggled(bool)), ui->socksVersion, SLOT(setEnabled(bool)));
- connect(ui->connectSocks, SIGNAL(clicked(bool)), this, SLOT(showRestartWarning_Proxy()));
ui->proxyIp->installEventFilter(this);
@@ -204,7 +203,7 @@ void OptionsDialog::on_resetButton_clicked()
if(btnRetVal == QMessageBox::Cancel)
return;
- /* reset all options and close Bitcoin-Qt */
+ /* reset all options and close GUI */
model->Reset();
QApplication::quit();
}
diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp
index 1133c457b3..a18fd1d514 100644
--- a/src/qt/optionsmodel.cpp
+++ b/src/qt/optionsmodel.cpp
@@ -19,6 +19,7 @@
#include "walletdb.h"
#endif
+#include <QNetworkProxy>
#include <QSettings>
#include <QStringList>
@@ -375,14 +376,25 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in
return successful;
}
-bool OptionsModel::getProxySettings(QString& proxyIP, quint16 &proxyPort) const
+bool OptionsModel::getProxySettings(QNetworkProxy& proxy) const
{
- std::string proxy = GetArg("-proxy", "");
- if (proxy.empty()) return false;
+ // Directly query current base proxy, because
+ // GUI settings can be overridden with -proxy.
+ proxyType curProxy;
+ if (GetProxy(NET_IPV4, curProxy)) {
+ if (curProxy.second == 5) {
+ proxy.setType(QNetworkProxy::Socks5Proxy);
+ proxy.setHostName(QString::fromStdString(curProxy.first.ToStringIP()));
+ proxy.setPort(curProxy.first.GetPort());
+
+ return true;
+ }
+ else
+ return false;
+ }
+ else
+ proxy.setType(QNetworkProxy::NoProxy);
- CService addrProxy(proxy);
- proxyIP = QString(addrProxy.ToStringIP().c_str());
- proxyPort = addrProxy.GetPort();
return true;
}
diff --git a/src/qt/optionsmodel.h b/src/qt/optionsmodel.h
index d05cb46746..7a71b772b2 100644
--- a/src/qt/optionsmodel.h
+++ b/src/qt/optionsmodel.h
@@ -7,6 +7,10 @@
#include <QAbstractListModel>
+QT_BEGIN_NAMESPACE
+class QNetworkProxy;
+QT_END_NAMESPACE
+
/** Interface from Qt to configuration data structure for Bitcoin client.
To Qt, the options are presented as a list with the different options
laid out vertically.
@@ -54,7 +58,7 @@ public:
bool getMinimizeOnClose() { return fMinimizeOnClose; }
int getDisplayUnit() { return nDisplayUnit; }
bool getDisplayAddresses() { return bDisplayAddresses; }
- bool getProxySettings(QString& proxyIP, quint16 &proxyPort) const;
+ bool getProxySettings(QNetworkProxy& proxy) const;
bool getCoinControlFeatures() { return fCoinControlFeatures; }
const QString& getOverriddenByCommandLine() { return strOverriddenByCommandLine; }
diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp
index 7642cd117a..ca6ae17990 100644
--- a/src/qt/paymentserver.cpp
+++ b/src/qt/paymentserver.cpp
@@ -335,17 +335,22 @@ void PaymentServer::initNetManager()
// netManager is used to fetch paymentrequests given in bitcoin: URIs
netManager = new QNetworkAccessManager(this);
- // Use proxy settings from optionsModel
- QString proxyIP;
- quint16 proxyPort;
- if (optionsModel->getProxySettings(proxyIP, proxyPort))
- {
- QNetworkProxy proxy;
- proxy.setType(QNetworkProxy::Socks5Proxy);
- proxy.setHostName(proxyIP);
- proxy.setPort(proxyPort);
- netManager->setProxy(proxy);
+ QNetworkProxy proxy;
+
+ // Query active proxy (fails if no SOCKS5 proxy)
+ if (optionsModel->getProxySettings(proxy)) {
+ if (proxy.type() == QNetworkProxy::Socks5Proxy) {
+ netManager->setProxy(proxy);
+
+ qDebug() << "PaymentServer::initNetManager : Using SOCKS5 proxy" << proxy.hostName() << ":" << proxy.port();
+ }
+ else
+ qDebug() << "PaymentServer::initNetManager : No active proxy server found.";
}
+ else
+ emit message(tr("Net manager warning"),
+ tr("Your active proxy doesn't support SOCKS5, which is required for payment requests via proxy."),
+ CClientUIInterface::MSG_WARNING);
connect(netManager, SIGNAL(finished(QNetworkReply*)),
this, SLOT(netRequestFinished(QNetworkReply*)));
diff --git a/src/qt/receivecoinsdialog.cpp b/src/qt/receivecoinsdialog.cpp
index 075a16dabf..38dc88f63b 100644
--- a/src/qt/receivecoinsdialog.cpp
+++ b/src/qt/receivecoinsdialog.cpp
@@ -55,6 +55,8 @@ void ReceiveCoinsDialog::setModel(WalletModel *model)
ui->recentRequestsView->horizontalHeader()->setSectionResizeMode(RecentRequestsTableModel::Message, QHeaderView::Stretch);
#endif
ui->recentRequestsView->horizontalHeader()->resizeSection(RecentRequestsTableModel::Amount, 100);
+
+ model->getRecentRequestsTableModel()->sort(RecentRequestsTableModel::Date, Qt::DescendingOrder);
}
}
diff --git a/src/qt/recentrequeststablemodel.cpp b/src/qt/recentrequeststablemodel.cpp
index 86c29dd02b..74b43f1d24 100644
--- a/src/qt/recentrequeststablemodel.cpp
+++ b/src/qt/recentrequeststablemodel.cpp
@@ -12,6 +12,13 @@ RecentRequestsTableModel::RecentRequestsTableModel(CWallet *wallet, WalletModel
walletModel(parent)
{
Q_UNUSED(wallet);
+ nReceiveRequestsMaxId = 0;
+
+ // Load entries from wallet
+ std::vector<std::string> vReceiveRequests;
+ parent->loadReceiveRequests(vReceiveRequests);
+ BOOST_FOREACH(const std::string& request, vReceiveRequests)
+ addNewRequest(request);
/* These columns must match the indices in the ColumnIndex enumeration */
columns << tr("Date") << tr("Label") << tr("Message") << tr("Amount");
@@ -104,6 +111,14 @@ bool RecentRequestsTableModel::removeRows(int row, int count, const QModelIndex
if(count > 0 && row >= 0 && (row+count) <= list.size())
{
+ const RecentRequestEntry *rec;
+ for (int i = 0; i < count; ++i)
+ {
+ rec = &list[row+i];
+ if (!walletModel->saveReceiveRequest(rec->recipient.address.toStdString(), rec->id, ""))
+ return false;
+ }
+
beginRemoveRows(parent, row, row + count - 1);
list.erase(list.begin() + row, list.begin() + row + count);
endRemoveRows();
@@ -118,12 +133,73 @@ Qt::ItemFlags RecentRequestsTableModel::flags(const QModelIndex &index) const
return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
}
+// called when adding a request from the GUI
void RecentRequestsTableModel::addNewRequest(const SendCoinsRecipient &recipient)
{
RecentRequestEntry newEntry;
+ newEntry.id = ++nReceiveRequestsMaxId;
newEntry.date = QDateTime::currentDateTime();
newEntry.recipient = recipient;
+
+ CDataStream ss(SER_DISK, CLIENT_VERSION);
+ ss << newEntry;
+
+ if (!walletModel->saveReceiveRequest(recipient.address.toStdString(), newEntry.id, ss.str()))
+ return;
+
+ addNewRequest(newEntry);
+}
+
+// called from ctor when loading from wallet
+void RecentRequestsTableModel::addNewRequest(const std::string &recipient)
+{
+ std::vector<char> data(recipient.begin(), recipient.end());
+ CDataStream ss(data, SER_DISK, CLIENT_VERSION);
+
+ RecentRequestEntry entry;
+ ss >> entry;
+
+ if (entry.id == 0) // should not happen
+ return;
+
+ if (entry.id > nReceiveRequestsMaxId)
+ nReceiveRequestsMaxId = entry.id;
+
+ addNewRequest(entry);
+}
+
+// actually add to table in GUI
+void RecentRequestsTableModel::addNewRequest(RecentRequestEntry &recipient)
+{
beginInsertRows(QModelIndex(), 0, 0);
- list.prepend(newEntry);
+ list.prepend(recipient);
endInsertRows();
}
+
+void RecentRequestsTableModel::sort(int column, Qt::SortOrder order)
+{
+ qSort(list.begin(), list.end(), RecentRequestEntryLessThan(column, order));
+ emit dataChanged(index(0, 0, QModelIndex()), index(list.size() - 1, NUMBER_OF_COLUMNS - 1, QModelIndex()));
+}
+
+bool RecentRequestEntryLessThan::operator()(RecentRequestEntry &left, RecentRequestEntry &right) const
+{
+ RecentRequestEntry *pLeft = &left;
+ RecentRequestEntry *pRight = &right;
+ if (order == Qt::DescendingOrder)
+ std::swap(pLeft, pRight);
+
+ switch(column)
+ {
+ case RecentRequestsTableModel::Date:
+ return pLeft->date.toTime_t() < pRight->date.toTime_t();
+ case RecentRequestsTableModel::Label:
+ return pLeft->recipient.label < pRight->recipient.label;
+ case RecentRequestsTableModel::Message:
+ return pLeft->recipient.message < pRight->recipient.message;
+ case RecentRequestsTableModel::Amount:
+ return pLeft->recipient.amount < pRight->recipient.amount;
+ default:
+ return pLeft->id < pRight->id;
+ }
+}
diff --git a/src/qt/recentrequeststablemodel.h b/src/qt/recentrequeststablemodel.h
index 3aab7b0a48..51aef9decf 100644
--- a/src/qt/recentrequeststablemodel.h
+++ b/src/qt/recentrequeststablemodel.h
@@ -13,10 +13,44 @@
class CWallet;
-struct RecentRequestEntry
+class RecentRequestEntry
{
+public:
+ RecentRequestEntry() : nVersion(RecentRequestEntry::CURRENT_VERSION), id(0) { }
+
+ static const int CURRENT_VERSION = 1;
+ int nVersion;
+ int64_t id;
QDateTime date;
SendCoinsRecipient recipient;
+
+ IMPLEMENT_SERIALIZE
+ (
+ RecentRequestEntry* pthis = const_cast<RecentRequestEntry*>(this);
+
+ unsigned int nDate = date.toTime_t();
+
+ READWRITE(pthis->nVersion);
+ nVersion = pthis->nVersion;
+ READWRITE(id);
+ READWRITE(nDate);
+ READWRITE(recipient);
+
+ if (fRead)
+ pthis->date = QDateTime::fromTime_t(nDate);
+ )
+};
+
+class RecentRequestEntryLessThan
+{
+public:
+ RecentRequestEntryLessThan(int nColumn, Qt::SortOrder fOrder):
+ column(nColumn), order(fOrder) {}
+ bool operator()(RecentRequestEntry &left, RecentRequestEntry &right) const;
+
+private:
+ int column;
+ Qt::SortOrder order;
};
/** Model for list of recently generated payment requests / bitcoin URIs.
@@ -34,7 +68,8 @@ public:
Date = 0,
Label = 1,
Message = 2,
- Amount = 3
+ Amount = 3,
+ NUMBER_OF_COLUMNS
};
/** @name Methods overridden from QAbstractTableModel
@@ -51,11 +86,17 @@ public:
const RecentRequestEntry &entry(int row) const { return list[row]; }
void addNewRequest(const SendCoinsRecipient &recipient);
+ void addNewRequest(const std::string &recipient);
+ void addNewRequest(RecentRequestEntry &recipient);
+
+public slots:
+ void sort(int column, Qt::SortOrder order = Qt::AscendingOrder);
private:
WalletModel *walletModel;
QStringList columns;
QList<RecentRequestEntry> list;
+ int64_t nReceiveRequestsMaxId;
};
#endif
diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp
index abb6ceb139..b1671b8a0e 100644
--- a/src/qt/rpcconsole.cpp
+++ b/src/qt/rpcconsole.cpp
@@ -7,7 +7,6 @@
#include "clientmodel.h"
#include "guiutil.h"
-#include "utilitydialog.h"
#include "rpcserver.h"
#include "rpcclient.h"
@@ -201,7 +200,6 @@ RPCConsole::RPCConsole(QWidget *parent) :
#ifndef Q_OS_MAC
ui->openDebugLogfileButton->setIcon(QIcon(":/icons/export"));
- ui->showCLOptionsButton->setIcon(QIcon(":/icons/options"));
#endif
// Install event filter for up and down arrow
@@ -442,12 +440,6 @@ void RPCConsole::scrollToEnd()
scrollbar->setValue(scrollbar->maximum());
}
-void RPCConsole::on_showCLOptionsButton_clicked()
-{
- HelpMessageDialog *help = new HelpMessageDialog(this);
- help->show();
-}
-
void RPCConsole::on_sldGraphRange_valueChanged(int value)
{
const int multiplier = 5; // each position on the slider represents 5 min
diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h
index 6fbf197728..0cfd1c80d1 100644
--- a/src/qt/rpcconsole.h
+++ b/src/qt/rpcconsole.h
@@ -40,8 +40,6 @@ private slots:
void on_tabWidget_currentChanged(int index);
/** open the debug.log from the current datadir */
void on_openDebugLogfileButton_clicked();
- /** display messagebox with program parameters (same as bitcoin-qt --help) */
- void on_showCLOptionsButton_clicked();
/** change the time range of the network traffic graph */
void on_sldGraphRange_valueChanged(int value);
/** update traffic statistics */
diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp
index 3f5d0cda3a..b4e74b078c 100644
--- a/src/qt/sendcoinsentry.cpp
+++ b/src/qt/sendcoinsentry.cpp
@@ -88,6 +88,9 @@ void SendCoinsEntry::clear()
ui->payTo->clear();
ui->addAsLabel->clear();
ui->payAmount->clear();
+ ui->messageTextLabel->clear();
+ ui->messageTextLabel->hide();
+ ui->messageLabel->hide();
// clear UI elements for insecure payment request
ui->payTo_is->clear();
ui->memoTextLabel_is->clear();
@@ -148,6 +151,7 @@ SendCoinsRecipient SendCoinsEntry::getValue()
recipient.address = ui->payTo->text();
recipient.label = ui->addAsLabel->text();
recipient.amount = ui->payAmount->value();
+ recipient.message = ui->messageTextLabel->text();
return recipient;
}
@@ -188,6 +192,11 @@ void SendCoinsEntry::setValue(const SendCoinsRecipient &value)
}
else // normal payment
{
+ // message
+ ui->messageTextLabel->setText(recipient.message);
+ ui->messageTextLabel->setVisible(!recipient.message.isEmpty());
+ ui->messageLabel->setVisible(!recipient.message.isEmpty());
+
ui->payTo->setText(recipient.address);
ui->addAsLabel->setText(recipient.label);
ui->payAmount->setValue(recipient.amount);
diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp
index 8b16496c18..c21679ea8a 100644
--- a/src/qt/splashscreen.cpp
+++ b/src/qt/splashscreen.cpp
@@ -5,8 +5,8 @@
#include "splashscreen.h"
#include "clientversion.h"
-#include "util.h"
#include "ui_interface.h"
+#include "util.h"
#include <QApplication>
#include <QPainter>
diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp
index c0c4d53732..2c3a9e3a5c 100644
--- a/src/qt/transactiondesc.cpp
+++ b/src/qt/transactiondesc.cpp
@@ -224,6 +224,11 @@ QString TransactionDesc::toHTML(CWallet *wallet, CWalletTx &wtx, int vout, int u
strHTML += "<b>" + tr("Transaction ID") + ":</b> " + TransactionRecord::formatSubTxId(wtx.GetHash(), vout) + "<br>";
+ // Message from normal bitcoin:URI (bitcoin:123...?message=example)
+ foreach (const PAIRTYPE(string, string)& r, wtx.vOrderForm)
+ if (r.first == "Message")
+ strHTML += "<br><b>" + tr("Message") + ":</b><br>" + GUIUtil::HtmlEscape(r.second, true) + "<br>";
+
//
// PaymentRequest info:
//
diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp
index 14f29c933b..ddc8c6ea79 100644
--- a/src/qt/walletmodel.cpp
+++ b/src/qt/walletmodel.cpp
@@ -269,6 +269,8 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(WalletModelTransaction &tran
rcp.paymentRequest.SerializeToString(&value);
newTx->vOrderForm.push_back(make_pair(key, value));
}
+ else if (!rcp.message.isEmpty()) // Message from normal bitcoin:URI (bitcoin:123...?message=example)
+ newTx->vOrderForm.push_back(make_pair("Message", rcp.message.toStdString()));
}
CReserveKey *keyChange = transaction.getPossibleKeyChange();
@@ -554,3 +556,27 @@ void WalletModel::listLockedCoins(std::vector<COutPoint>& vOutpts)
LOCK(wallet->cs_wallet);
wallet->ListLockedCoins(vOutpts);
}
+
+void WalletModel::loadReceiveRequests(std::vector<std::string>& vReceiveRequests)
+{
+ LOCK(wallet->cs_wallet);
+ BOOST_FOREACH(const PAIRTYPE(CTxDestination, CAddressBookData)& item, wallet->mapAddressBook)
+ BOOST_FOREACH(const PAIRTYPE(std::string, std::string)& item2, item.second.destdata)
+ if (item2.first.size() > 2 && item2.first.substr(0,2) == "rr") // receive request
+ vReceiveRequests.push_back(item2.second);
+}
+
+bool WalletModel::saveReceiveRequest(const std::string &sAddress, const int64_t nId, const std::string &sRequest)
+{
+ CTxDestination dest = CBitcoinAddress(sAddress).Get();
+
+ std::stringstream ss;
+ ss << nId;
+ std::string key = "rr" + ss.str(); // "rr" prefix = "receive request" in destdata
+
+ LOCK(wallet->cs_wallet);
+ if (sRequest.empty())
+ return wallet->EraseDestData(dest, key);
+ else
+ return wallet->AddDestData(dest, key, sRequest);
+}
diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h
index 1a4d25615a..6d9d866b25 100644
--- a/src/qt/walletmodel.h
+++ b/src/qt/walletmodel.h
@@ -36,9 +36,9 @@ QT_END_NAMESPACE
class SendCoinsRecipient
{
public:
- explicit SendCoinsRecipient() : amount(0) { }
+ explicit SendCoinsRecipient() : amount(0), nVersion(SendCoinsRecipient::CURRENT_VERSION) { }
explicit SendCoinsRecipient(const QString &addr, const QString &label, quint64 amount, const QString &message):
- address(addr), label(label), amount(amount), message(message) {}
+ address(addr), label(label), amount(amount), message(message), nVersion(SendCoinsRecipient::CURRENT_VERSION) {}
// If from an insecure payment request, this is used for storing
// the addresses, e.g. address-A<br />address-B<br />address-C.
@@ -55,6 +55,41 @@ public:
PaymentRequestPlus paymentRequest;
// Empty if no authentication or invalid signature/cert/etc.
QString authenticatedMerchant;
+
+ static const int CURRENT_VERSION = 1;
+ int nVersion;
+
+ IMPLEMENT_SERIALIZE
+ (
+ SendCoinsRecipient* pthis = const_cast<SendCoinsRecipient*>(this);
+
+ std::string sAddress = pthis->address.toStdString();
+ std::string sLabel = pthis->label.toStdString();
+ std::string sMessage = pthis->message.toStdString();
+ std::string sPaymentRequest;
+ if (!fRead && pthis->paymentRequest.IsInitialized())
+ pthis->paymentRequest.SerializeToString(&sPaymentRequest);
+ std::string sAuthenticatedMerchant = pthis->authenticatedMerchant.toStdString();
+
+ READWRITE(pthis->nVersion);
+ nVersion = pthis->nVersion;
+ READWRITE(sAddress);
+ READWRITE(sLabel);
+ READWRITE(amount);
+ READWRITE(sMessage);
+ READWRITE(sPaymentRequest);
+ READWRITE(sAuthenticatedMerchant);
+
+ if (fRead)
+ {
+ pthis->address = QString::fromStdString(sAddress);
+ pthis->label = QString::fromStdString(sLabel);
+ pthis->message = QString::fromStdString(sMessage);
+ if (!sPaymentRequest.empty())
+ pthis->paymentRequest.parse(QByteArray::fromRawData(sPaymentRequest.data(), sPaymentRequest.size()));
+ pthis->authenticatedMerchant = QString::fromStdString(sAuthenticatedMerchant);
+ }
+ )
};
/** Interface to Bitcoin wallet from Qt view code. */
@@ -152,6 +187,9 @@ public:
void unlockCoin(COutPoint& output);
void listLockedCoins(std::vector<COutPoint>& vOutpts);
+ void loadReceiveRequests(std::vector<std::string>& vReceiveRequests);
+ bool saveReceiveRequest(const std::string &sAddress, const int64_t nId, const std::string &sRequest);
+
private:
CWallet *wallet;
diff --git a/src/rpcdump.cpp b/src/rpcdump.cpp
index c801b284cb..18c8bb6e61 100644
--- a/src/rpcdump.cpp
+++ b/src/rpcdump.cpp
@@ -116,9 +116,14 @@ Value importprivkey(const Array& params, bool fHelp)
if (pwalletMain->HaveKey(vchAddress))
return Value::null;
+ pwalletMain->mapKeyMetadata[vchAddress].nCreateTime = 1;
+
if (!pwalletMain->AddKeyPubKey(key, pubkey))
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding key to wallet");
+ // whenever a key is imported, we need to scan the whole chain
+ pwalletMain->nTimeFirstKey = 1; // 0 would be considered 'no value'
+
if (fRescan) {
pwalletMain->ScanForWalletTransactions(chainActive.Genesis(), true);
pwalletMain->ReacceptWalletTransactions();
diff --git a/src/wallet.cpp b/src/wallet.cpp
index 9065ba8483..84642bee62 100644
--- a/src/wallet.cpp
+++ b/src/wallet.cpp
@@ -1534,7 +1534,19 @@ bool CWallet::SetAddressBook(const CTxDestination& address, const string& strNam
bool CWallet::DelAddressBook(const CTxDestination& address)
{
+
AssertLockHeld(cs_wallet); // mapAddressBook
+
+ if(fFileBacked)
+ {
+ // Delete destdata tuples associated with address
+ std::string strAddress = CBitcoinAddress(address).ToString();
+ BOOST_FOREACH(const PAIRTYPE(string, string) &item, mapAddressBook[address].destdata)
+ {
+ CWalletDB(strWalletFile).EraseDestData(strAddress, item.first);
+ }
+ }
+
mapAddressBook.erase(address);
NotifyAddressBookChanged(this, address, "", ::IsMine(*this, address), "", CT_DELETED);
if (!fFileBacked)
@@ -2008,3 +2020,45 @@ void CWallet::GetKeyBirthTimes(std::map<CKeyID, int64_t> &mapKeyBirth) const {
for (std::map<CKeyID, CBlockIndex*>::const_iterator it = mapKeyFirstBlock.begin(); it != mapKeyFirstBlock.end(); it++)
mapKeyBirth[it->first] = it->second->nTime - 7200; // block times can be 2h off
}
+
+bool CWallet::AddDestData(const CTxDestination &dest, const std::string &key, const std::string &value)
+{
+ if (boost::get<CNoDestination>(&dest))
+ return false;
+
+ mapAddressBook[dest].destdata.insert(std::make_pair(key, value));
+ if (!fFileBacked)
+ return true;
+ return CWalletDB(strWalletFile).WriteDestData(CBitcoinAddress(dest).ToString(), key, value);
+}
+
+bool CWallet::EraseDestData(const CTxDestination &dest, const std::string &key)
+{
+ if (!mapAddressBook[dest].destdata.erase(key))
+ return false;
+ if (!fFileBacked)
+ return true;
+ return CWalletDB(strWalletFile).EraseDestData(CBitcoinAddress(dest).ToString(), key);
+}
+
+bool CWallet::LoadDestData(const CTxDestination &dest, const std::string &key, const std::string &value)
+{
+ mapAddressBook[dest].destdata.insert(std::make_pair(key, value));
+ return true;
+}
+
+bool CWallet::GetDestData(const CTxDestination &dest, const std::string &key, std::string *value) const
+{
+ std::map<CTxDestination, CAddressBookData>::const_iterator i = mapAddressBook.find(dest);
+ if(i != mapAddressBook.end())
+ {
+ CAddressBookData::StringMap::const_iterator j = i->second.destdata.find(key);
+ if(j != i->second.destdata.end())
+ {
+ if(value)
+ *value = j->second;
+ return true;
+ }
+ }
+ return false;
+}
diff --git a/src/wallet.h b/src/wallet.h
index e4452a3093..dc8c007ac8 100644
--- a/src/wallet.h
+++ b/src/wallet.h
@@ -83,6 +83,9 @@ public:
{
purpose = "unknown";
}
+
+ typedef std::map<std::string, std::string> StringMap;
+ StringMap destdata;
};
/** A CWallet is an extension of a keystore, which also maintains a set of transactions and balances,
@@ -189,6 +192,15 @@ public:
bool AddCScript(const CScript& redeemScript);
bool LoadCScript(const CScript& redeemScript) { return CCryptoKeyStore::AddCScript(redeemScript); }
+ /// Adds a destination data tuple to the store, and saves it to disk
+ bool AddDestData(const CTxDestination &dest, const std::string &key, const std::string &value);
+ /// Erases a destination data tuple in the store and on disk
+ bool EraseDestData(const CTxDestination &dest, const std::string &key);
+ /// Adds a destination data tuple to the store, without saving it to disk
+ bool LoadDestData(const CTxDestination &dest, const std::string &key, const std::string &value);
+ /// Look up a destination data tuple in the store, return true if found false otherwise
+ bool GetDestData(const CTxDestination &dest, const std::string &key, std::string *value) const;
+
bool Unlock(const SecureString& strWalletPassphrase);
bool ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase);
bool EncryptWallet(const SecureString& strWalletPassphrase);
diff --git a/src/walletdb.cpp b/src/walletdb.cpp
index 9c5bddba60..2e61c6cd58 100644
--- a/src/walletdb.cpp
+++ b/src/walletdb.cpp
@@ -564,6 +564,18 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
{
ssValue >> pwallet->nOrderPosNext;
}
+ else if (strType == "destdata")
+ {
+ std::string strAddress, strKey, strValue;
+ ssKey >> strAddress;
+ ssKey >> strKey;
+ ssValue >> strValue;
+ if (!pwallet->LoadDestData(CBitcoinAddress(strAddress).Get(), strKey, strValue))
+ {
+ strErr = "Error reading wallet database: LoadDestData failed";
+ return false;
+ }
+ }
} catch (...)
{
return false;
@@ -865,3 +877,15 @@ bool CWalletDB::Recover(CDBEnv& dbenv, std::string filename)
{
return CWalletDB::Recover(dbenv, filename, false);
}
+
+bool CWalletDB::WriteDestData(const std::string &address, const std::string &key, const std::string &value)
+{
+ nWalletDBUpdated++;
+ return Write(boost::make_tuple(std::string("destdata"), address, key), value);
+}
+
+bool CWalletDB::EraseDestData(const std::string &address, const std::string &key)
+{
+ nWalletDBUpdated++;
+ return Erase(boost::make_tuple(string("destdata"), address, key));
+}
diff --git a/src/walletdb.h b/src/walletdb.h
index 88ba89f9d5..15af287245 100644
--- a/src/walletdb.h
+++ b/src/walletdb.h
@@ -124,6 +124,11 @@ public:
bool ReadAccount(const std::string& strAccount, CAccount& account);
bool WriteAccount(const std::string& strAccount, const CAccount& account);
+
+ /// Write destination data key,value tuple to database
+ bool WriteDestData(const std::string &address, const std::string &key, const std::string &value);
+ /// Erase destination data tuple from wallet database
+ bool EraseDestData(const std::string &address, const std::string &key);
private:
bool WriteAccountingEntry(const uint64_t nAccEntryNum, const CAccountingEntry& acentry);
public: