Browse Source

Merge pull request #3145

395d0d5 rework an ugly hack in processPaymentRequest() (Philip Kaufmann)
952d2cd make processPaymentRequest() use a single SendCoinsRecipient (Philip Kaufmann)
983cef4 payment-request UI: use SendCoinsRecipient.message for memo (Philip Kaufmann)
c6c97e0 [Qt] Rework of payment request UI (mainly for insecure pr) (Philip Kaufmann)
0.10
Wladimir J. van der Laan 11 years ago
parent
commit
65d0fc4b73
No known key found for this signature in database
GPG Key ID: 74810B012346C9A6
  1. 11
      src/qt/forms/sendcoinsdialog.ui
  2. 514
      src/qt/forms/sendcoinsentry.ui
  3. 92
      src/qt/paymentserver.cpp
  4. 2
      src/qt/paymentserver.h
  5. 10
      src/qt/sendcoinsdialog.cpp
  6. 66
      src/qt/sendcoinsentry.cpp
  7. 4
      src/qt/walletmodel.cpp
  8. 11
      src/qt/walletmodel.h

11
src/qt/forms/sendcoinsdialog.ui

@ -29,7 +29,16 @@ @@ -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>

514
src/qt/forms/sendcoinsentry.ui

@ -10,13 +10,19 @@ @@ -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 @@ @@ -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 @@ @@ -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 @@ @@ -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">

92
src/qt/paymentserver.cpp

@ -280,9 +280,6 @@ PaymentServer::PaymentServer(QObject* parent, bool startLocalServer) : @@ -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) @@ -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) @@ -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 @@ -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 @@ -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) @@ -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";

2
src/qt/paymentserver.h

@ -113,7 +113,7 @@ private slots: @@ -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);

10
src/qt/sendcoinsdialog.cpp

@ -106,7 +106,7 @@ void SendCoinsDialog::on_sendButton_clicked() @@ -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() @@ -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) @@ -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())

66
src/qt/sendcoinsentry.cpp

@ -22,7 +22,7 @@ SendCoinsEntry::SendCoinsEntry(QWidget *parent) : @@ -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) : @@ -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) @@ -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) @@ -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() @@ -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() @@ -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) @@ -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) @@ -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() @@ -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());
}
}

4
src/qt/walletmodel.cpp

@ -262,8 +262,8 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(WalletModelTransaction &tran @@ -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();

11
src/qt/walletmodel.h

@ -29,14 +29,21 @@ public: @@ -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: @@ -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:

Loading…
Cancel
Save