From 5c83f797c5bcbebe4c2646044f968205980b2350 Mon Sep 17 00:00:00 2001 From: Philip Kaufmann Date: Sun, 24 Jun 2012 18:28:05 +0200 Subject: [PATCH] update QRCodeDialog - remove unused #include 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 --- src/qt/addressbookpage.cpp | 9 ++ src/qt/addressbookpage.h | 3 + src/qt/bitcoingui.cpp | 2 + src/qt/forms/qrcodedialog.ui | 242 +++++++++++++++++------------------ src/qt/guiconstants.h | 6 + src/qt/qrcodedialog.cpp | 87 +++++++++---- src/qt/qrcodedialog.h | 22 ++-- 7 files changed, 217 insertions(+), 154 deletions(-) diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp index 5849f5b23..663ff6866 100644 --- a/src/qt/addressbookpage.cpp +++ b/src/qt/addressbookpage.cpp @@ -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(); } diff --git a/src/qt/addressbookpage.h b/src/qt/addressbookpage.h index b2e91c7cb..e94c55613 100644 --- a/src/qt/addressbookpage.h +++ b/src/qt/addressbookpage.h @@ -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; diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index c642f4aa0..3ef03c437 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -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()); } } diff --git a/src/qt/forms/qrcodedialog.ui b/src/qt/forms/qrcodedialog.ui index 6199b6874..52e9db376 100644 --- a/src/qt/forms/qrcodedialog.ui +++ b/src/qt/forms/qrcodedialog.ui @@ -6,8 +6,8 @@ 0 0 - 334 - 425 + 340 + 530 @@ -28,8 +28,8 @@ 300 - - QR Code + + Qt::PlainText Qt::AlignCenter @@ -39,134 +39,123 @@ + + + + + 0 + 0 + + + + + 0 + 50 + + + + true + + + Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + - - - - - - - true - - - Request Payment - - - - - - - - - - 0 - 0 - - - - Amount: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - lnReqAmount - - - - - - - false - - - - 60 - 0 - - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - 0 - 0 - - - - BTC - - - lnReqAmount - - - - - - + + + true + + + Request Payment + + + + + + + QFormLayout::AllNonFixedFieldsGrow + + + + + Label: + + + Qt::PlainText + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + lnLabel + + - - - - - - Label: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - lnLabel - - - - - - - - 100 - 0 - - - - - - - - Message: - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - lnMessage - - - - - - - - 100 - 0 - - - - - + + + + + + + Message: + + + Qt::PlainText + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + lnMessage + + + + + + + + + + + 0 + 0 + + + + Amount: + + + Qt::PlainText + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + lnReqAmount + + + + + + + false + + + + 80 + 0 + + + - + @@ -194,6 +183,13 @@ + + + BitcoinAmountField + QSpinBox +
bitcoinamountfield.h
+
+
diff --git a/src/qt/guiconstants.h b/src/qt/guiconstants.h index 54e9d644f..6f6fa7f26 100644 --- a/src/qt/guiconstants.h +++ b/src/qt/guiconstants.h @@ -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 diff --git a/src/qt/qrcodedialog.cpp b/src/qt/qrcodedialog.cpp index 32e5462ce..ca9497512 100644 --- a/src/qt/qrcodedialog.cpp +++ b/src/qt/qrcodedialog.cpp @@ -1,28 +1,34 @@ #include "qrcodedialog.h" #include "ui_qrcodedialog.h" + +#include "bitcoinunits.h" +#include "guiconstants.h" #include "guiutil.h" +#include "optionsmodel.h" #include #include -#include #include -#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()); + } +} diff --git a/src/qt/qrcodedialog.h b/src/qt/qrcodedialog.h index ad0611605..c55c34bce 100644 --- a/src/qt/qrcodedialog.h +++ b/src/qt/qrcodedialog.h @@ -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(); -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_btnSaveAs_clicked(); + void setModel(OptionsModel *model); - void on_chkReqPayment_toggled(bool checked); +private slots: + void on_lnReqAmount_textChanged(); + void on_lnLabel_textChanged(); + void on_lnMessage_textChanged(); + void on_btnSaveAs_clicked(); + void on_chkReqPayment_toggled(bool fChecked); + + void updateDisplayUnit(); private: Ui::QRCodeDialog *ui; + OptionsModel *model; + QString address; QImage myImage; - QString getURI(); - QString address; - void genCode(); + QString getURI(); }; #endif // QRCODEDIALOG_H