aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/qt/addressbookpage.cpp7
-rw-r--r--src/qt/addressbookpage.h3
-rw-r--r--src/qt/forms/sendcoinsdialog.ui11
-rw-r--r--src/qt/forms/sendcoinsentry.ui514
-rw-r--r--src/qt/intro.cpp4
-rw-r--r--src/qt/paymentserver.cpp92
-rw-r--r--src/qt/paymentserver.h2
-rw-r--r--src/qt/sendcoinsdialog.cpp10
-rw-r--r--src/qt/sendcoinsentry.cpp66
-rw-r--r--src/qt/walletmodel.cpp4
-rw-r--r--src/qt/walletmodel.h11
11 files changed, 616 insertions, 108 deletions
diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp
index 021f33ff20..cef307b86d 100644
--- a/src/qt/addressbookpage.cpp
+++ b/src/qt/addressbookpage.cpp
@@ -10,7 +10,6 @@
#include "ui_addressbookpage.h"
#include "addresstablemodel.h"
-#include "optionsmodel.h"
#include "bitcoingui.h"
#include "editaddressdialog.h"
#include "csvmodelwriter.h"
@@ -25,7 +24,6 @@ AddressBookPage::AddressBookPage(Mode mode, Tabs tab, QWidget *parent) :
QDialog(parent),
ui(new Ui::AddressBookPage),
model(0),
- optionsModel(0),
mode(mode),
tab(tab)
{
@@ -148,11 +146,6 @@ void AddressBookPage::setModel(AddressTableModel *model)
selectionChanged();
}
-void AddressBookPage::setOptionsModel(OptionsModel *optionsModel)
-{
- this->optionsModel = optionsModel;
-}
-
void AddressBookPage::on_copyAddress_clicked()
{
GUIUtil::copyEntryData(ui->tableView, AddressTableModel::Address);
diff --git a/src/qt/addressbookpage.h b/src/qt/addressbookpage.h
index 081bfae365..60b5d8c47f 100644
--- a/src/qt/addressbookpage.h
+++ b/src/qt/addressbookpage.h
@@ -11,7 +11,6 @@ namespace Ui {
class AddressBookPage;
}
class AddressTableModel;
-class OptionsModel;
QT_BEGIN_NAMESPACE
class QTableView;
@@ -42,7 +41,6 @@ public:
~AddressBookPage();
void setModel(AddressTableModel *model);
- void setOptionsModel(OptionsModel *optionsModel);
const QString &getReturnValue() const { return returnValue; }
public slots:
@@ -51,7 +49,6 @@ public slots:
private:
Ui::AddressBookPage *ui;
AddressTableModel *model;
- OptionsModel *optionsModel;
Mode mode;
Tabs tab;
QString returnValue;
diff --git a/src/qt/forms/sendcoinsdialog.ui b/src/qt/forms/sendcoinsdialog.ui
index 67ea45d2fd..7547931ff1 100644
--- a/src/qt/forms/sendcoinsdialog.ui
+++ b/src/qt/forms/sendcoinsdialog.ui
@@ -29,7 +29,16 @@
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2" stretch="0,1">
- <property name="margin">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
<number>0</number>
</property>
<item>
diff --git a/src/qt/forms/sendcoinsentry.ui b/src/qt/forms/sendcoinsentry.ui
index db742d633d..199a14598a 100644
--- a/src/qt/forms/sendcoinsentry.ui
+++ b/src/qt/forms/sendcoinsentry.ui
@@ -10,13 +10,19 @@
<height>150</height>
</rect>
</property>
+ <property name="focusPolicy">
+ <enum>Qt::TabFocus</enum>
+ </property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="currentIndex">
<number>0</number>
</property>
- <widget class="QFrame" name="SendCoinsInsecure">
+ <widget class="QFrame" name="SendCoins">
+ <property name="toolTip">
+ <string>This is a normal payment.</string>
+ </property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
@@ -143,7 +149,495 @@
</item>
</layout>
</widget>
- <widget class="QFrame" name="SendCoinsSecure">
+ <widget class="QFrame" name="SendCoins_InsecurePaymentRequest">
+ <property name="palette">
+ <palette>
+ <active>
+ <colorrole role="WindowText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Button">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Light">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Midlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>191</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Dark">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>127</red>
+ <green>127</green>
+ <blue>63</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Mid">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>170</red>
+ <green>170</green>
+ <blue>84</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Text">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="BrightText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ButtonText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Base">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Window">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Shadow">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="AlternateBase">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>191</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ToolTipBase">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>220</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ToolTipText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </active>
+ <inactive>
+ <colorrole role="WindowText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Button">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Light">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Midlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>191</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Dark">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>127</red>
+ <green>127</green>
+ <blue>63</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Mid">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>170</red>
+ <green>170</green>
+ <blue>84</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Text">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="BrightText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ButtonText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Base">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Window">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Shadow">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="AlternateBase">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>191</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ToolTipBase">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>220</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ToolTipText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </inactive>
+ <disabled>
+ <colorrole role="WindowText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>127</red>
+ <green>127</green>
+ <blue>63</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Button">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Light">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Midlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>191</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Dark">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>127</red>
+ <green>127</green>
+ <blue>63</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Mid">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>170</red>
+ <green>170</green>
+ <blue>84</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Text">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>127</red>
+ <green>127</green>
+ <blue>63</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="BrightText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>255</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ButtonText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>127</red>
+ <green>127</green>
+ <blue>63</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Base">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Window">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="Shadow">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="AlternateBase">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>127</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ToolTipBase">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>255</red>
+ <green>255</green>
+ <blue>220</blue>
+ </color>
+ </brush>
+ </colorrole>
+ <colorrole role="ToolTipText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </brush>
+ </colorrole>
+ </disabled>
+ </palette>
+ </property>
+ <property name="toolTip">
+ <string>This is an unverified payment request.</string>
+ </property>
+ <property name="autoFillBackground">
+ <bool>true</bool>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Sunken</enum>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_is">
+ <property name="spacing">
+ <number>12</number>
+ </property>
+ <item row="4" column="0">
+ <widget class="QLabel" name="memoLabel_is">
+ <property name="text">
+ <string>Memo:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0">
+ <widget class="QLabel" name="amountLabel_is">
+ <property name="text">
+ <string>Amount:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="payToLabel_is">
+ <property name="text">
+ <string>Pay To:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="2">
+ <widget class="BitcoinAmountField" name="payAmount_is">
+ <property name="acceptDrops">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="2">
+ <layout class="QHBoxLayout" name="payToLayout_is">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="payTo_is"/>
+ </item>
+ </layout>
+ </item>
+ <item row="4" column="2">
+ <widget class="QLabel" name="memoTextLabel_is">
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QFrame" name="SendCoins_SecurePaymentRequest">
<property name="palette">
<palette>
<active>
@@ -586,6 +1080,9 @@
</disabled>
</palette>
</property>
+ <property name="toolTip">
+ <string>This is a verified payment request.</string>
+ </property>
<property name="autoFillBackground">
<bool>true</bool>
</property>
@@ -607,35 +1104,26 @@
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
- <property name="buddy">
- <cstring>addAsLabel</cstring>
- </property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="amountLabel_s">
<property name="text">
- <string>A&amp;mount:</string>
+ <string>Amount:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
- <property name="buddy">
- <cstring>payAmount_s</cstring>
- </property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="payToLabel_s">
<property name="text">
- <string>Pay &amp;To:</string>
+ <string>Pay To:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
- <property name="buddy">
- <cstring>payTo_s</cstring>
- </property>
</widget>
</item>
<item row="5" column="2">
diff --git a/src/qt/intro.cpp b/src/qt/intro.cpp
index 60ddbc1e3b..e7e7682258 100644
--- a/src/qt/intro.cpp
+++ b/src/qt/intro.cpp
@@ -181,8 +181,8 @@ void Intro::pickDataDirectory(bool fIsTestnet)
fs::create_directory(dataDir.toStdString());
break;
} catch(fs::filesystem_error &e) {
- QMessageBox::critical(0, QObject::tr("Bitcoin"),
- QObject::tr("Error: Specified data directory \"%1\" can not be created.").arg(dataDir));
+ QMessageBox::critical(0, tr("Bitcoin"),
+ tr("Error: Specified data directory \"%1\" can not be created.").arg(dataDir));
/* fall through, back to choosing screen */
}
}
diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp
index f3dbaa350f..87db4bbf34 100644
--- a/src/qt/paymentserver.cpp
+++ b/src/qt/paymentserver.cpp
@@ -280,9 +280,6 @@ PaymentServer::PaymentServer(QObject* parent, bool startLocalServer) :
connect(this, SIGNAL(receivedPaymentACK(QString)), this, SLOT(handlePaymentACK(QString)));
}
}
-
- // netManager is null until uiReady() is called
- netManager = NULL;
}
PaymentServer::~PaymentServer()
@@ -378,6 +375,7 @@ void PaymentServer::handleURIOrFile(const QString& s)
fetchRequest(fetchUrl);
else
qDebug() << "PaymentServer::handleURIOrFile : Invalid URL: " << fetchUrl;
+
return;
}
@@ -388,18 +386,17 @@ void PaymentServer::handleURIOrFile(const QString& s)
emit 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);
+
return;
}
if (QFile::exists(s))
{
PaymentRequestPlus request;
- QList<SendCoinsRecipient> recipients;
- if (readPaymentRequest(s, request) && processPaymentRequest(request, recipients)) {
- foreach (const SendCoinsRecipient& recipient, recipients){
- emit receivedPaymentRequest(recipient);
- }
- }
+ SendCoinsRecipient recipient;
+ if (readPaymentRequest(s, request) && processPaymentRequest(request, recipient))
+ emit receivedPaymentRequest(recipient);
+
return;
}
}
@@ -445,14 +442,37 @@ bool PaymentServer::readPaymentRequest(const QString& filename, PaymentRequestPl
return request.parse(data);
}
-bool PaymentServer::processPaymentRequest(PaymentRequestPlus& request, QList<SendCoinsRecipient>& recipients)
+bool PaymentServer::processPaymentRequest(PaymentRequestPlus& request, SendCoinsRecipient& recipient)
{
if (!optionsModel)
return false;
- QList<std::pair<CScript,qint64> > sendingTos = request.getPayTo();
- qint64 totalAmount = 0;
+ recipient.paymentRequest = request;
+ recipient.message = GUIUtil::HtmlEscape(request.getDetails().memo());
+
+ request.getMerchant(PaymentServer::certStore, recipient.authenticatedMerchant);
+
+ QList<std::pair<CScript, qint64> > sendingTos = request.getPayTo();
+ QStringList addresses;
+
foreach(const PAIRTYPE(CScript, qint64)& sendingTo, sendingTos) {
+ // Extract and check destination addresses
+ CTxDestination dest;
+ if (ExtractDestination(sendingTo.first, dest)) {
+ // Append destination address
+ addresses.append(QString::fromStdString(CBitcoinAddress(dest).ToString()));
+ }
+ else if (!recipient.authenticatedMerchant.isEmpty()){
+ // Insecure payments to custom bitcoin addresses are not supported
+ // (there is no good way to tell the user where they are paying in a way
+ // they'd have a chance of understanding).
+ emit message(tr("Payment request error"),
+ tr("Unverified payment requests to custom payment scripts are unsupported."),
+ CClientUIInterface::MSG_ERROR);
+ return false;
+ }
+
+ // Extract and check amounts
CTxOut txOut(sendingTo.second, sendingTo.first);
if (txOut.IsDust(CTransaction::nMinRelayTxFee)) {
QString msg = tr("Requested payment amount of %1 is too small (considered dust).")
@@ -463,43 +483,16 @@ bool PaymentServer::processPaymentRequest(PaymentRequestPlus& request, QList<Sen
return false;
}
- totalAmount += sendingTo.second;
+ recipient.amount += sendingTo.second;
}
+ // Store addresses and format them to fit nicely into the GUI
+ recipient.address = addresses.join("<br />");
- recipients.append(SendCoinsRecipient());
-
- if (request.getMerchant(PaymentServer::certStore, recipients[0].authenticatedMerchant)) {
- recipients[0].paymentRequest = request;
- recipients[0].amount = totalAmount;
- qDebug() << "PaymentServer::processPaymentRequest : Payment request from " << recipients[0].authenticatedMerchant;
+ if (!recipient.authenticatedMerchant.isEmpty()) {
+ qDebug() << "PaymentServer::processPaymentRequest : Secure payment request from " << recipient.authenticatedMerchant;
}
else {
- recipients.clear();
- // Insecure payment requests may turn into more than one recipient if
- // the merchant is requesting payment to more than one address.
- for (int i = 0; i < sendingTos.size(); i++) {
- std::pair<CScript, qint64>& sendingTo = sendingTos[i];
- recipients.append(SendCoinsRecipient());
- recipients[i].amount = sendingTo.second;
- QString memo = QString::fromStdString(request.getDetails().memo());
- recipients[i].label = GUIUtil::HtmlEscape(memo);
- CTxDestination dest;
- if (ExtractDestination(sendingTo.first, dest)) {
- if (i == 0) // Tie request to first pay-to, we don't want multiple ACKs
- recipients[i].paymentRequest = request;
- recipients[i].address = QString::fromStdString(CBitcoinAddress(dest).ToString());
- qDebug() << "PaymentServer::processPaymentRequest : Payment request, insecure " << recipients[i].address;
- }
- else {
- // Insecure payments to custom bitcoin addresses are not supported
- // (there is no good way to tell the user where they are paying in a way
- // they'd have a chance of understanding).
- emit message(tr("Payment request error"),
- tr("Insecure requests to custom payment scripts unsupported"),
- CClientUIInterface::MSG_ERROR);
- return false;
- }
- }
+ qDebug() << "PaymentServer::processPaymentRequest : Insecure payment request to " << addresses.join(", ");
}
return true;
@@ -590,12 +583,9 @@ void PaymentServer::netRequestFinished(QNetworkReply* reply)
if (requestType == "PaymentRequest")
{
PaymentRequestPlus request;
- QList<SendCoinsRecipient> recipients;
- if (request.parse(data) && processPaymentRequest(request, recipients)) {
- foreach (const SendCoinsRecipient& recipient, recipients) {
- emit receivedPaymentRequest(recipient);
- }
- }
+ SendCoinsRecipient recipient;
+ if (request.parse(data) && processPaymentRequest(request, recipient))
+ emit receivedPaymentRequest(recipient);
else
qDebug() << "PaymentServer::netRequestFinished : Error processing payment request";
diff --git a/src/qt/paymentserver.h b/src/qt/paymentserver.h
index 9d62479d7f..76cdb819d7 100644
--- a/src/qt/paymentserver.h
+++ b/src/qt/paymentserver.h
@@ -113,7 +113,7 @@ private slots:
private:
static bool readPaymentRequest(const QString& filename, PaymentRequestPlus& request);
- bool processPaymentRequest(PaymentRequestPlus& request, QList<SendCoinsRecipient>& recipients);
+ bool processPaymentRequest(PaymentRequestPlus& request, SendCoinsRecipient& recipient);
void handleURIOrFile(const QString& s);
void fetchRequest(const QUrl& url);
diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp
index ec2712d8f2..2490c64835 100644
--- a/src/qt/sendcoinsdialog.cpp
+++ b/src/qt/sendcoinsdialog.cpp
@@ -106,7 +106,7 @@ void SendCoinsDialog::on_sendButton_clicked()
QString recipientElement;
- if (rcp.authenticatedMerchant.isEmpty())
+ if (!rcp.paymentRequest.IsInitialized()) // normal payment
{
if(rcp.label.length() > 0) // label with address
{
@@ -118,10 +118,14 @@ void SendCoinsDialog::on_sendButton_clicked()
recipientElement = tr("%1 to %2").arg(amount, address);
}
}
- else // just merchant
+ else if(!rcp.authenticatedMerchant.isEmpty()) // secure payment request
{
recipientElement = tr("%1 to %2").arg(amount, GUIUtil::HtmlEscape(rcp.authenticatedMerchant));
}
+ else // insecure payment request
+ {
+ recipientElement = tr("%1 to %2").arg(amount, address);
+ }
formatted.append(recipientElement);
}
@@ -317,7 +321,7 @@ void SendCoinsDialog::pasteEntry(const SendCoinsRecipient &rv)
bool SendCoinsDialog::handlePaymentRequest(const SendCoinsRecipient &rv)
{
QString strSendCoins = tr("Send Coins");
- if (!rv.authenticatedMerchant.isEmpty()) {
+ if (rv.paymentRequest.IsInitialized()) {
// Expired payment request?
const payments::PaymentDetails& details = rv.paymentRequest.getDetails();
if (details.has_expires() && (int64)details.expires() < GetTime())
diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp
index b7f684c483..490b9caf5e 100644
--- a/src/qt/sendcoinsentry.cpp
+++ b/src/qt/sendcoinsentry.cpp
@@ -22,7 +22,7 @@ SendCoinsEntry::SendCoinsEntry(QWidget *parent) :
{
ui->setupUi(this);
- setCurrentWidget(ui->SendCoinsInsecure);
+ setCurrentWidget(ui->SendCoins);
#ifdef Q_OS_MAC
ui->payToLayout->setSpacing(4);
@@ -32,10 +32,12 @@ SendCoinsEntry::SendCoinsEntry(QWidget *parent) :
ui->addAsLabel->setPlaceholderText(tr("Enter a label for this address to add it to your address book"));
ui->payTo->setPlaceholderText(tr("Enter a Bitcoin address (e.g. 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJDE9L)"));
#endif
- setFocusPolicy(Qt::TabFocus);
setFocusProxy(ui->payTo);
+ // normal bitcoin address field
GUIUtil::setupAddressWidget(ui->payTo, this);
+ // just a label for displaying bitcoin address(es)
+ ui->payTo_is->setFont(GUIUtil::bitcoinAddressFont());
}
SendCoinsEntry::~SendCoinsEntry()
@@ -71,7 +73,7 @@ void SendCoinsEntry::setModel(WalletModel *model)
{
this->model = model;
- if(model && model->getOptionsModel())
+ if (model && model->getOptionsModel())
connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));
clear();
@@ -84,11 +86,15 @@ void SendCoinsEntry::setRemoveEnabled(bool enabled)
void SendCoinsEntry::clear()
{
- // clear UI elements for insecure payments
+ // clear UI elements for normal payment
ui->payTo->clear();
ui->addAsLabel->clear();
ui->payAmount->clear();
- // and the ones for secure payments just to be sure
+ // clear UI elements for insecure payment request
+ ui->payTo_is->clear();
+ ui->memoTextLabel_is->clear();
+ ui->payAmount_is->clear();
+ // clear UI elements for secure payment request
ui->payTo_s->clear();
ui->memoTextLabel_s->clear();
ui->payAmount_s->clear();
@@ -106,20 +112,23 @@ void SendCoinsEntry::on_deleteButton_clicked()
bool SendCoinsEntry::validate()
{
+ if (!model)
+ return false;
+
// Check input validity
bool retval = true;
- if (!recipient.authenticatedMerchant.isEmpty())
+ // Skip checks for payment request
+ if (recipient.paymentRequest.IsInitialized())
return retval;
- if (!ui->payTo->hasAcceptableInput() ||
- (model && !model->validateAddress(ui->payTo->text())))
+ if (!ui->payTo->hasAcceptableInput() || !model->validateAddress(ui->payTo->text()))
{
ui->payTo->setValid(false);
retval = false;
}
- if(!ui->payAmount->validate())
+ if (!ui->payAmount->validate())
{
retval = false;
}
@@ -135,10 +144,11 @@ bool SendCoinsEntry::validate()
SendCoinsRecipient SendCoinsEntry::getValue()
{
- if (!recipient.authenticatedMerchant.isEmpty())
+ // Payment request
+ if (recipient.paymentRequest.IsInitialized())
return recipient;
- // User-entered or non-authenticated:
+ // Normal payment
recipient.address = ui->payTo->text();
recipient.label = ui->addAsLabel->text();
recipient.amount = ui->payAmount->value();
@@ -160,22 +170,31 @@ void SendCoinsEntry::setValue(const SendCoinsRecipient &value)
{
recipient = value;
- if (recipient.authenticatedMerchant.isEmpty())
+ if (recipient.paymentRequest.IsInitialized()) // payment request
+ {
+ if (recipient.authenticatedMerchant.isEmpty()) // insecure
+ {
+ ui->payTo_is->setText(recipient.address);
+ ui->memoTextLabel_is->setText(recipient.message);
+ ui->payAmount_is->setValue(recipient.amount);
+ ui->payAmount_is->setReadOnly(true);
+ setCurrentWidget(ui->SendCoins_InsecurePaymentRequest);
+ }
+ else // secure
+ {
+ ui->payTo_s->setText(recipient.authenticatedMerchant);
+ ui->memoTextLabel_s->setText(recipient.message);
+ ui->payAmount_s->setValue(recipient.amount);
+ ui->payAmount_s->setReadOnly(true);
+ setCurrentWidget(ui->SendCoins_SecurePaymentRequest);
+ }
+ }
+ else // normal payment
{
ui->payTo->setText(recipient.address);
ui->addAsLabel->setText(recipient.label);
ui->payAmount->setValue(recipient.amount);
}
- else
- {
- const payments::PaymentDetails& details = recipient.paymentRequest.getDetails();
-
- ui->payTo_s->setText(recipient.authenticatedMerchant);
- ui->memoTextLabel_s->setText(QString::fromStdString(details.memo()));
- ui->payAmount_s->setValue(recipient.amount);
- ui->payAmount_s->setReadOnly(true);
- setCurrentWidget(ui->SendCoinsSecure);
- }
}
void SendCoinsEntry::setAddress(const QString &address)
@@ -186,7 +205,7 @@ void SendCoinsEntry::setAddress(const QString &address)
bool SendCoinsEntry::isClear()
{
- return ui->payTo->text().isEmpty() && ui->payTo_s->text().isEmpty();
+ return ui->payTo->text().isEmpty() && ui->payTo_is->text().isEmpty() && ui->payTo_s->text().isEmpty();
}
void SendCoinsEntry::setFocus()
@@ -200,6 +219,7 @@ void SendCoinsEntry::updateDisplayUnit()
{
// Update payAmount with the current unit
ui->payAmount->setDisplayUnit(model->getOptionsModel()->getDisplayUnit());
+ ui->payAmount_is->setDisplayUnit(model->getOptionsModel()->getDisplayUnit());
ui->payAmount_s->setDisplayUnit(model->getOptionsModel()->getDisplayUnit());
}
}
diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp
index d95e718946..1c24ffb20b 100644
--- a/src/qt/walletmodel.cpp
+++ b/src/qt/walletmodel.cpp
@@ -262,8 +262,8 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(WalletModelTransaction &tran
// and emit coinsSent signal for each recipient
foreach(const SendCoinsRecipient &rcp, transaction.getRecipients())
{
- // Don't touch the address book when we have a secure payment-request
- if (rcp.authenticatedMerchant.isEmpty())
+ // Don't touch the address book when we have a payment request
+ if (!rcp.paymentRequest.IsInitialized())
{
std::string strAddress = rcp.address.toStdString();
CTxDestination dest = CBitcoinAddress(strAddress).Get();
diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h
index b9a0a7601e..efa6ccc668 100644
--- a/src/qt/walletmodel.h
+++ b/src/qt/walletmodel.h
@@ -29,14 +29,21 @@ public:
explicit SendCoinsRecipient(const QString &addr, const QString &label, quint64 amount, const QString &message):
address(addr), label(label), amount(amount), message(message) {}
+ // If from an insecure payment request, this is used for storing
+ // the addresses, e.g. address-A<br />address-B<br />address-C.
+ // Info: As we don't need to process addresses in here when using
+ // payment requests, we can abuse it for displaying an address list.
+ // Todo: This is a hack, should be replaced with a cleaner solution!
QString address;
QString label;
qint64 amount;
+ // If from a payment request, this is used for storing the memo
QString message;
// If from a payment request, paymentRequest.IsInitialized() will be true
PaymentRequestPlus paymentRequest;
- QString authenticatedMerchant; // Empty if no authentication or invalid signature/cert/etc.
+ // Empty if no authentication or invalid signature/cert/etc.
+ QString authenticatedMerchant;
};
/** Interface to Bitcoin wallet from Qt view code. */
@@ -164,7 +171,7 @@ signals:
// this means that the unlocking failed or was cancelled.
void requireUnlock();
- // Asynchronous message notification
+ // Fired when a message should be reported to the user
void message(const QString &title, const QString &message, unsigned int style);
// Coins sent: from wallet, to recipient, in (serialized) transaction: