Browse Source

update QRCodeDialog

- remove unused #include <QDebug> and lblBTC label
- update Bitcoin input field to a BitcoinAmountField to allow Bitcoin unit selection
- use BitcoinUnits::format for the resulting amount parameter in the generated URI (always use BTC as per BIP21)
- move MAX_URI_LENGTH and EXPORT_IMAGE_SIZE to guiconstants.h
- add OptionsModel in AddressBookPage and use it in on_showQRCode_clicked() to pass it to QRCodeDialog
- add OptionsModel in QRCodeDialog to enable display unit updates
- add updateDisplayUnit() slot to be able to imediately update currently set bitcoin unit
- make all labels in the UI-file plain text
- resize dialog to match for an updated layout (fields are now stacked and new field)
- remove unused parameters from private slots
- only enable save button, when QR Code was generated
- show message when entered amound is invalid
- add read-only QPlainTextEdit field to output generated URI
tags/v0.15.1
Philip Kaufmann 9 years ago
parent
commit
5c83f797c5

+ 9
- 0
src/qt/addressbookpage.cpp View File

@@ -2,6 +2,7 @@
#include "ui_addressbookpage.h"

#include "addresstablemodel.h"
#include "optionsmodel.h"
#include "bitcoingui.h"
#include "editaddressdialog.h"
#include "csvmodelwriter.h"
@@ -20,6 +21,7 @@ AddressBookPage::AddressBookPage(Mode mode, Tabs tab, QWidget *parent) :
QDialog(parent),
ui(new Ui::AddressBookPage),
model(0),
optionsModel(0),
mode(mode),
tab(tab)
{
@@ -139,6 +141,11 @@ void AddressBookPage::setModel(AddressTableModel *model)
selectionChanged();
}

void AddressBookPage::setOptionsModel(OptionsModel *optionsModel)
{
this->optionsModel = optionsModel;
}

void AddressBookPage::on_copyToClipboard_clicked()
{
GUIUtil::copyEntryData(ui->tableView, AddressTableModel::Address);
@@ -314,6 +321,8 @@ void AddressBookPage::on_showQRCode_clicked()
QString address = index.data().toString(), label = index.sibling(index.row(), 0).data(Qt::EditRole).toString();

QRCodeDialog *dialog = new QRCodeDialog(address, label, tab == ReceivingTab, this);
if(optionsModel)
dialog->setModel(optionsModel);
dialog->setAttribute(Qt::WA_DeleteOnClose);
dialog->show();
}

+ 3
- 0
src/qt/addressbookpage.h View File

@@ -7,6 +7,7 @@ namespace Ui {
class AddressBookPage;
}
class AddressTableModel;
class OptionsModel;

QT_BEGIN_NAMESPACE
class QTableView;
@@ -37,6 +38,7 @@ public:
~AddressBookPage();

void setModel(AddressTableModel *model);
void setOptionsModel(OptionsModel *optionsModel);
const QString &getReturnValue() const { return returnValue; }

public slots:
@@ -46,6 +48,7 @@ public slots:
private:
Ui::AddressBookPage *ui;
AddressTableModel *model;
OptionsModel *optionsModel;
Mode mode;
Tabs tab;
QString returnValue;

+ 2
- 0
src/qt/bitcoingui.cpp View File

@@ -357,6 +357,8 @@ void BitcoinGUI::setClientModel(ClientModel *clientModel)
connect(clientModel, SIGNAL(error(QString,QString,bool)), this, SLOT(error(QString,QString,bool)));

rpcConsole->setClientModel(clientModel);
addressBookPage->setOptionsModel(clientModel->getOptionsModel());
receiveCoinsPage->setOptionsModel(clientModel->getOptionsModel());
}
}


+ 119
- 123
src/qt/forms/qrcodedialog.ui View File

@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>334</width>
<height>425</height>
<width>340</width>
<height>530</height>
</rect>
</property>
<property name="windowTitle">
@@ -28,8 +28,8 @@
<height>300</height>
</size>
</property>
<property name="text">
<string>QR Code</string>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
@@ -39,134 +39,123 @@
</property>
</widget>
</item>
<item>
<widget class="QPlainTextEdit" name="outUri">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>50</height>
</size>
</property>
<property name="tabChangesFocus">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="widget" native="true">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QCheckBox" name="chkReqPayment">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Request Payment</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="lblAmount">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Amount:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>lnReqAmount</cstring>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lnReqAmount">
<property name="enabled">
<bool>false</bool>
</property>
<property name="minimumSize">
<size>
<width>60</width>
<height>0</height>
</size>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblBTC">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>BTC</string>
</property>
<property name="buddy">
<cstring>lnReqAmount</cstring>
</property>
</widget>
</item>
</layout>
</item>
</layout>
<widget class="QCheckBox" name="chkReqPayment">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Request Payment</string>
</property>
</widget>
</item>
<item>
<layout class="QFormLayout" name="formLayout">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<item row="1" column="0">
<widget class="QLabel" name="lblLabel">
<property name="text">
<string>Label:</string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>lnLabel</cstring>
</property>
</widget>
</item>
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="lblLabel">
<property name="text">
<string>Label:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>lnLabel</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="lnLabel">
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="lblMessage">
<property name="text">
<string>Message:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>lnMessage</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="lnMessage">
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
</widget>
</item>
</layout>
<item row="1" column="1">
<widget class="QLineEdit" name="lnLabel"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="lblMessage">
<property name="text">
<string>Message:</string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>lnMessage</cstring>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="lnMessage"/>
</item>
<item row="0" column="0">
<widget class="QLabel" name="lblAmount">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Amount:</string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>lnReqAmount</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="BitcoinAmountField" name="lnReqAmount">
<property name="enabled">
<bool>false</bool>
</property>
<property name="minimumSize">
<size>
<width>80</width>
<height>0</height>
</size>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
@@ -194,6 +183,13 @@
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>BitcoinAmountField</class>
<extends>QSpinBox</extends>
<header>bitcoinamountfield.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>

+ 6
- 0
src/qt/guiconstants.h View File

@@ -25,4 +25,10 @@ static const int STATUSBAR_ICONSIZE = 16;
*/
static const int TOOLTIP_WRAP_THRESHOLD = 80;

/* Maximum allowed URI length */
static const int MAX_URI_LENGTH = 255;

/* QRCodeDialog -- size of exported QR Code image */
#define EXPORT_IMAGE_SIZE 256

#endif // GUICONSTANTS_H

+ 65
- 22
src/qt/qrcodedialog.cpp View File

@@ -1,28 +1,34 @@
#include "qrcodedialog.h"
#include "ui_qrcodedialog.h"

#include "bitcoinunits.h"
#include "guiconstants.h"
#include "guiutil.h"
#include "optionsmodel.h"

#include <QPixmap>
#include <QUrl>
#include <QDebug>

#include <qrencode.h>

#define EXPORT_IMAGE_SIZE 256

QRCodeDialog::QRCodeDialog(const QString &addr, const QString &label, bool enableReq, QWidget *parent) :
QDialog(parent), ui(new Ui::QRCodeDialog), address(addr)
QDialog(parent),
ui(new Ui::QRCodeDialog),
model(0),
address(addr)
{
ui->setupUi(this);

setWindowTitle(QString("%1").arg(address));

ui->chkReqPayment->setVisible(enableReq);
ui->lnReqAmount->setVisible(enableReq);
ui->lblAmount->setVisible(enableReq);
ui->lblBTC->setVisible(enableReq);
ui->lnReqAmount->setVisible(enableReq);

ui->lnLabel->setText(label);

ui->btnSaveAs->setEnabled(false);

genCode();
}

@@ -31,6 +37,17 @@ QRCodeDialog::~QRCodeDialog()
delete ui;
}

void QRCodeDialog::setModel(OptionsModel *model)
{
this->model = model;

if (model)
connect(model, SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));

// update the display unit, to not use the default ("BTC")
updateDisplayUnit();
}

void QRCodeDialog::genCode()
{
QString uri = getURI();
@@ -57,26 +74,34 @@ void QRCodeDialog::genCode()
}
}
QRcode_free(code);

ui->lblQRCode->setPixmap(QPixmap::fromImage(myImage).scaled(300, 300));

ui->outUri->setPlainText(uri);
}
else
ui->lblQRCode->setText(tr("Resulting URI too long, try to reduce the text for label / message."));
}

QString QRCodeDialog::getURI()
{
QString ret = QString("bitcoin:%1").arg(address);

int paramCount = 0;
if (ui->chkReqPayment->isChecked() && !ui->lnReqAmount->text().isEmpty())

ui->outUri->clear();

if (ui->chkReqPayment->isChecked())
{
bool ok = false;
ui->lnReqAmount->text().toDouble(&ok);
if (ok)
if (ui->lnReqAmount->validate())
{
ret += QString("?amount=%1").arg(ui->lnReqAmount->text());
// even if we allow a non BTC unit input in lnReqAmount, we generate the URI with BTC as unit (as defined in BIP21)
ret += QString("?amount=%1").arg(BitcoinUnits::format(BitcoinUnits::BTC, ui->lnReqAmount->value()));
paramCount++;
}
else
{
ui->btnSaveAs->setEnabled(false);
ui->lblQRCode->setText(tr("The entered amount is invalid, please check."));
return QString("");
}
}

if (!ui->lnLabel->text().isEmpty())
@@ -93,24 +118,29 @@ QString QRCodeDialog::getURI()
paramCount++;
}

// limit URI length to 255 chars, to prevent a DoS against the QR-Code dialog
if (ret.length() < 256)
return ret;
else
// limit URI length to prevent a DoS against the QR-Code dialog
if (ret.length() > MAX_URI_LENGTH)
{
ui->btnSaveAs->setEnabled(false);
ui->lblQRCode->setText(tr("Resulting URI too long, try to reduce the text for label / message."));
return QString("");
}

ui->btnSaveAs->setEnabled(true);
return ret;
}

void QRCodeDialog::on_lnReqAmount_textChanged(const QString &arg1)
void QRCodeDialog::on_lnReqAmount_textChanged()
{
genCode();
}

void QRCodeDialog::on_lnLabel_textChanged(const QString &arg1)
void QRCodeDialog::on_lnLabel_textChanged()
{
genCode();
}

void QRCodeDialog::on_lnMessage_textChanged(const QString &arg1)
void QRCodeDialog::on_lnMessage_textChanged()
{
genCode();
}
@@ -122,7 +152,20 @@ void QRCodeDialog::on_btnSaveAs_clicked()
myImage.scaled(EXPORT_IMAGE_SIZE, EXPORT_IMAGE_SIZE).save(fn);
}

void QRCodeDialog::on_chkReqPayment_toggled(bool)
void QRCodeDialog::on_chkReqPayment_toggled(bool fChecked)
{
if (!fChecked)
// if chkReqPayment is not active, don't display lnReqAmount as invalid
ui->lnReqAmount->setValid(true);

genCode();
}

void QRCodeDialog::updateDisplayUnit()
{
if (model)
{
// Update lnReqAmount with the current unit
ui->lnReqAmount->setDisplayUnit(model->getDisplayUnit());
}
}

+ 11
- 7
src/qt/qrcodedialog.h View File

@@ -7,6 +7,7 @@
namespace Ui {
class QRCodeDialog;
}
class OptionsModel;

class QRCodeDialog : public QDialog
{
@@ -16,22 +17,25 @@ public:
explicit QRCodeDialog(const QString &addr, const QString &label, bool enableReq, QWidget *parent = 0);
~QRCodeDialog();

void setModel(OptionsModel *model);

private slots:
void on_lnReqAmount_textChanged(const QString &arg1);
void on_lnLabel_textChanged(const QString &arg1);
void on_lnMessage_textChanged(const QString &arg1);
void on_lnReqAmount_textChanged();
void on_lnLabel_textChanged();
void on_lnMessage_textChanged();
void on_btnSaveAs_clicked();
void on_chkReqPayment_toggled(bool fChecked);

void on_chkReqPayment_toggled(bool checked);
void updateDisplayUnit();

private:
Ui::QRCodeDialog *ui;
QImage myImage;

QString getURI();
OptionsModel *model;
QString address;
QImage myImage;

void genCode();
QString getURI();
};

#endif // QRCODEDIALOG_H

Loading…
Cancel
Save