From 74fb765e29ed2b85ee7f6e61d16876c03b4abe9b Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Wed, 16 Oct 2013 15:14:26 +0200 Subject: [PATCH 1/8] qt: rework "receive coins" workflow --- contrib/bitcoin-qt.pro | 4 +- src/qt/Makefile.am | 16 +- src/qt/addressbookpage.cpp | 52 ++---- src/qt/addressbookpage.h | 4 +- src/qt/bitcoingui.cpp | 26 ++- src/qt/bitcoingui.h | 6 +- src/qt/forms/addressbookpage.ui | 13 +- src/qt/forms/receivecoinsdialog.ui | 164 ++++++++++++++++++ ...rcodedialog.ui => receiverequestdialog.ui} | 155 ++++++++++------- src/qt/receivecoinsdialog.cpp | 105 +++++++++++ src/qt/receivecoinsdialog.h | 38 ++++ ...odedialog.cpp => receiverequestdialog.cpp} | 93 +++++----- ...{qrcodedialog.h => receiverequestdialog.h} | 11 +- src/qt/sendcoinsentry.cpp | 2 +- src/qt/signverifymessagedialog.cpp | 4 +- src/qt/walletframe.cpp | 21 ++- src/qt/walletframe.h | 7 +- src/qt/walletview.cpp | 41 +++-- src/qt/walletview.h | 12 +- 19 files changed, 536 insertions(+), 238 deletions(-) create mode 100644 src/qt/forms/receivecoinsdialog.ui rename src/qt/forms/{qrcodedialog.ui => receiverequestdialog.ui} (64%) create mode 100644 src/qt/receivecoinsdialog.cpp create mode 100644 src/qt/receivecoinsdialog.h rename src/qt/{qrcodedialog.cpp => receiverequestdialog.cpp} (60%) rename src/qt/{qrcodedialog.h => receiverequestdialog.h} (65%) diff --git a/contrib/bitcoin-qt.pro b/contrib/bitcoin-qt.pro index 0b181ef449..7087709741 100644 --- a/contrib/bitcoin-qt.pro +++ b/contrib/bitcoin-qt.pro @@ -11,7 +11,9 @@ FORMS += \ ../src/qt/forms/editaddressdialog.ui \ ../src/qt/forms/askpassphrasedialog.ui \ ../src/qt/forms/addressbookpage.ui \ - ../src/qt/forms/aboutdialog.ui + ../src/qt/forms/aboutdialog.ui \ + ../src/qt/forms/receivecoinsdialog.ui \ + ../src/qt/forms/receiverequestdialog.ui RESOURCES += \ ../src/qt/bitcoin.qrc diff --git a/src/qt/Makefile.am b/src/qt/Makefile.am index 5892f6aca0..4ecd5629ea 100644 --- a/src/qt/Makefile.am +++ b/src/qt/Makefile.am @@ -34,7 +34,8 @@ QT_TS = locale/bitcoin_ach.ts locale/bitcoin_af_ZA.ts locale/bitcoin_ar.ts \ QT_FORMS_UI = forms/aboutdialog.ui forms/addressbookpage.ui \ forms/askpassphrasedialog.ui forms/editaddressdialog.ui forms/intro.ui \ - forms/optionsdialog.ui forms/overviewpage.ui forms/qrcodedialog.ui \ + forms/optionsdialog.ui forms/overviewpage.ui forms/receiverequestdialog.ui \ + forms/receivecoinsdialog.ui \ forms/rpcconsole.ui forms/sendcoinsdialog.ui forms/sendcoinsentry.ui \ forms/signverifymessagedialog.ui forms/transactiondescdialog.ui @@ -46,7 +47,8 @@ QT_MOC_CPP = moc_aboutdialog.cpp moc_addressbookpage.cpp \ moc_intro.cpp moc_macdockiconhandler.cpp moc_macnotificationhandler.cpp \ moc_monitoreddatamapper.cpp moc_notificator.cpp moc_optionsdialog.cpp \ moc_optionsmodel.cpp moc_overviewpage.cpp moc_paymentserver.cpp \ - moc_qrcodedialog.cpp moc_qvalidatedlineedit.cpp moc_qvaluecombobox.cpp \ + moc_receiverequestdialog.cpp moc_qvalidatedlineedit.cpp moc_qvaluecombobox.cpp \ + moc_receivecoinsdialog.cpp \ moc_rpcconsole.cpp moc_sendcoinsdialog.cpp moc_sendcoinsentry.cpp \ moc_signverifymessagedialog.cpp moc_splashscreen.cpp moc_trafficgraphwidget.cpp moc_transactiondesc.cpp \ moc_transactiondescdialog.cpp moc_transactionfilterproxy.cpp \ @@ -54,7 +56,6 @@ QT_MOC_CPP = moc_aboutdialog.cpp moc_addressbookpage.cpp \ moc_walletmodel.cpp moc_walletview.cpp BITCOIN_MM = macdockiconhandler.mm macnotificationhandler.mm -QR_CPP = qrcodedialog.cpp QT_MOC = intro.moc overviewpage.moc rpcconsole.moc @@ -71,7 +72,8 @@ BITCOIN_QT_H = aboutdialog.h addressbookpage.h addresstablemodel.h \ editaddressdialog.h guiconstants.h guiutil.h intro.h macdockiconhandler.h \ macnotificationhandler.h monitoreddatamapper.h notificator.h optionsdialog.h \ optionsmodel.h overviewpage.h paymentrequestplus.h paymentserver.h \ - qrcodedialog.h qvalidatedlineedit.h qvaluecombobox.h rpcconsole.h \ + receivecoinsdialog.h \ + receiverequestdialog.h qvalidatedlineedit.h qvaluecombobox.h rpcconsole.h \ sendcoinsdialog.h sendcoinsentry.h signverifymessagedialog.h splashscreen.h \ trafficgraphwidget.h transactiondescdialog.h transactiondesc.h transactionfilterproxy.h \ transactionrecord.h transactiontablemodel.h transactionview.h walletframe.h \ @@ -101,6 +103,7 @@ BITCOIN_QT_CPP = aboutdialog.cpp addressbookpage.cpp \ guiutil.cpp intro.cpp monitoreddatamapper.cpp notificator.cpp \ optionsdialog.cpp optionsmodel.cpp overviewpage.cpp paymentrequestplus.cpp \ paymentserver.cpp qvalidatedlineedit.cpp qvaluecombobox.cpp \ + receivecoinsdialog.cpp receiverequestdialog.cpp \ rpcconsole.cpp sendcoinsdialog.cpp sendcoinsentry.cpp \ signverifymessagedialog.cpp splashscreen.cpp trafficgraphwidget.cpp transactiondesc.cpp \ transactiondescdialog.cpp transactionfilterproxy.cpp transactionrecord.cpp \ @@ -135,9 +138,6 @@ endif if TARGET_WINDOWS libbitcoinqt_a_SOURCES += $(BITCOIN_RC) endif -if USE_QRCODE - libbitcoinqt_a_SOURCES += $(QR_CPP) -endif # # bitcoin-qt binary # @@ -159,7 +159,7 @@ QT_QM=$(QT_TS:.ts=.qm) bitcoinstrings.cpp: FORCE $(MAKE) -C $(top_srcdir)/src qt/bitcoinstrings.cpp -translate: bitcoinstrings.cpp $(QT_FORMS_UI) $(QT_FORMS_UI) $(BITCOIN_QT_CPP) $(BITCOIN_QT_H) $(BITCOIN_MM) $(QR_CPP) +translate: bitcoinstrings.cpp $(QT_FORMS_UI) $(QT_FORMS_UI) $(BITCOIN_QT_CPP) $(BITCOIN_QT_H) $(BITCOIN_MM) @test -n $(LUPDATE) || echo "lupdate is required for updating translations" @$(LUPDATE) $^ -locations relative -no-obsolete -ts locale/bitcoin_en.ts diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp index 5b8d44481e..c9718c37bc 100644 --- a/src/qt/addressbookpage.cpp +++ b/src/qt/addressbookpage.cpp @@ -12,10 +12,6 @@ #include "csvmodelwriter.h" #include "guiutil.h" -#ifdef USE_QRCODE -#include "qrcodedialog.h" -#endif - #include #include #include @@ -40,20 +36,25 @@ AddressBookPage::AddressBookPage(Mode mode, Tabs tab, QWidget *parent) : ui->exportButton->setIcon(QIcon()); #endif -#ifndef USE_QRCODE - ui->showQRCode->setVisible(false); -#endif - switch(mode) { - case ForSending: + case ForSelection: + switch(tab) + { + case SendingTab: setWindowTitle(tr("Choose the address to send coins to")); break; + case ReceivingTab: setWindowTitle(tr("Choose the address to receive coins with")); break; + } connect(ui->tableView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(accept())); ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers); ui->tableView->setFocus(); ui->exportButton->hide(); break; case ForEditing: - ui->buttonBox->setVisible(false); + switch(tab) + { + case SendingTab: setWindowTitle(tr("Sending addresses")); break; + case ReceivingTab: setWindowTitle(tr("Receiving addresses")); break; + } break; } switch(tab) @@ -64,7 +65,7 @@ AddressBookPage::AddressBookPage(Mode mode, Tabs tab, QWidget *parent) : ui->signMessage->setVisible(false); break; case ReceivingTab: - ui->labelExplanation->setText(tr("These are your Bitcoin addresses for receiving payments. You may want to give a different one to each sender so you can keep track of who is paying you.")); + ui->labelExplanation->setText(tr("These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.")); ui->deleteAddress->setVisible(false); ui->signMessage->setVisible(true); break; @@ -75,7 +76,6 @@ AddressBookPage::AddressBookPage(Mode mode, Tabs tab, QWidget *parent) : QAction *copyLabelAction = new QAction(tr("Copy &Label"), this); QAction *editAction = new QAction(tr("&Edit"), this); QAction *sendCoinsAction = new QAction(tr("Send &Coins"), this); - QAction *showQRCodeAction = new QAction(ui->showQRCode->text(), this); QAction *signMessageAction = new QAction(ui->signMessage->text(), this); QAction *verifyMessageAction = new QAction(ui->verifyMessage->text(), this); deleteAction = new QAction(ui->deleteAddress->text(), this); @@ -90,9 +90,6 @@ AddressBookPage::AddressBookPage(Mode mode, Tabs tab, QWidget *parent) : contextMenu->addSeparator(); if(tab == SendingTab) contextMenu->addAction(sendCoinsAction); -#ifdef USE_QRCODE - contextMenu->addAction(showQRCodeAction); -#endif if(tab == ReceivingTab) contextMenu->addAction(signMessageAction); else if(tab == SendingTab) @@ -104,7 +101,6 @@ AddressBookPage::AddressBookPage(Mode mode, Tabs tab, QWidget *parent) : connect(editAction, SIGNAL(triggered()), this, SLOT(onEditAction())); connect(deleteAction, SIGNAL(triggered()), this, SLOT(on_deleteAddress_clicked())); connect(sendCoinsAction, SIGNAL(triggered()), this, SLOT(onSendCoinsAction())); - connect(showQRCodeAction, SIGNAL(triggered()), this, SLOT(on_showQRCode_clicked())); connect(signMessageAction, SIGNAL(triggered()), this, SLOT(on_signMessage_clicked())); connect(verifyMessageAction, SIGNAL(triggered()), this, SLOT(on_verifyMessage_clicked())); @@ -295,12 +291,10 @@ void AddressBookPage::selectionChanged() break; } ui->copyAddress->setEnabled(true); - ui->showQRCode->setEnabled(true); } else { ui->deleteAddress->setEnabled(false); - ui->showQRCode->setEnabled(false); ui->copyAddress->setEnabled(false); ui->signMessage->setEnabled(false); ui->verifyMessage->setEnabled(false); @@ -312,9 +306,6 @@ void AddressBookPage::done(int retval) QTableView *table = ui->tableView; if(!table->selectionModel() || !table->model()) return; - // When this is a tab/widget and not a model dialog, ignore "done" - if(mode == ForEditing) - return; // Figure out which address was selected, and return it QModelIndexList indexes = table->selectionModel()->selectedRows(AddressTableModel::Address); @@ -358,25 +349,6 @@ void AddressBookPage::on_exportButton_clicked() } } -void AddressBookPage::on_showQRCode_clicked() -{ -#ifdef USE_QRCODE - QTableView *table = ui->tableView; - QModelIndexList indexes = table->selectionModel()->selectedRows(AddressTableModel::Address); - - foreach (QModelIndex index, indexes) - { - QString address = index.data().toString(); - QString label = index.sibling(index.row(), 0).data(Qt::EditRole).toString(); - - QRCodeDialog *dialog = new QRCodeDialog(address, label, tab == ReceivingTab, this); - dialog->setModel(optionsModel); - dialog->setAttribute(Qt::WA_DeleteOnClose); - dialog->show(); - } -#endif -} - void AddressBookPage::contextualMenu(const QPoint &point) { QModelIndex index = ui->tableView->indexAt(point); diff --git a/src/qt/addressbookpage.h b/src/qt/addressbookpage.h index 34465aa65f..70ff3984be 100644 --- a/src/qt/addressbookpage.h +++ b/src/qt/addressbookpage.h @@ -30,7 +30,7 @@ public: }; enum Mode { - ForSending, /**< Open address book to pick address for sending */ + ForSelection, /**< Open address book to pick address */ ForEditing /**< Open address book for editing */ }; @@ -69,8 +69,6 @@ private slots: void on_verifyMessage_clicked(); /** Open send coins dialog for currently selected address (no button) */ void onSendCoinsAction(); - /** Generate a QR Code from the currently selected address */ - void on_showQRCode_clicked(); /** Copy label of currently selected address entry to clipboard (no button) */ void onCopyLabelAction(); /** Edit currently selected address entry (no button) */ diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 3336a8afd3..5bcbf3cfdf 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -207,13 +207,6 @@ void BitcoinGUI::createActions(bool fIsTestnet) historyAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_4)); tabGroup->addAction(historyAction); - addressBookAction = new QAction(QIcon(":/icons/address-book"), tr("&Addresses"), this); - addressBookAction->setStatusTip(tr("Edit the list of stored addresses and labels")); - addressBookAction->setToolTip(addressBookAction->statusTip()); - addressBookAction->setCheckable(true); - addressBookAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_5)); - tabGroup->addAction(addressBookAction); - connect(overviewAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); connect(overviewAction, SIGNAL(triggered()), this, SLOT(gotoOverviewPage())); connect(sendCoinsAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); @@ -222,8 +215,6 @@ void BitcoinGUI::createActions(bool fIsTestnet) connect(receiveCoinsAction, SIGNAL(triggered()), this, SLOT(gotoReceiveCoinsPage())); connect(historyAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); connect(historyAction, SIGNAL(triggered()), this, SLOT(gotoHistoryPage())); - connect(addressBookAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized())); - connect(addressBookAction, SIGNAL(triggered()), this, SLOT(gotoAddressBookPage())); quitAction = new QAction(QIcon(":/icons/quit"), tr("E&xit"), this); quitAction->setStatusTip(tr("Quit application")); @@ -266,6 +257,11 @@ void BitcoinGUI::createActions(bool fIsTestnet) openRPCConsoleAction = new QAction(QIcon(":/icons/debugwindow"), tr("&Debug window"), this); openRPCConsoleAction->setStatusTip(tr("Open debugging and diagnostic console")); + usedSendingAddressesAction = new QAction(QIcon(":/icons/address-book"), tr("&Used sending addresses..."), this); + usedSendingAddressesAction->setStatusTip(tr("Edit the list of used sending addresses and labels")); + usedReceivingAddressesAction = new QAction(QIcon(":/icons/address-book"), tr("Used &receiving addresses..."), this); + usedReceivingAddressesAction->setStatusTip(tr("Edit the list of used receiving addresses and labels")); + connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit())); connect(aboutAction, SIGNAL(triggered()), this, SLOT(aboutClicked())); connect(aboutQtAction, SIGNAL(triggered()), qApp, SLOT(aboutQt())); @@ -276,6 +272,8 @@ void BitcoinGUI::createActions(bool fIsTestnet) connect(changePassphraseAction, SIGNAL(triggered()), walletFrame, SLOT(changePassphrase())); connect(signMessageAction, SIGNAL(triggered()), this, SLOT(gotoSignMessageTab())); connect(verifyMessageAction, SIGNAL(triggered()), this, SLOT(gotoVerifyMessageTab())); + connect(usedSendingAddressesAction, SIGNAL(triggered()), walletFrame, SLOT(usedSendingAddresses())); + connect(usedReceivingAddressesAction, SIGNAL(triggered()), walletFrame, SLOT(usedReceivingAddresses())); } void BitcoinGUI::createMenuBar() @@ -294,6 +292,9 @@ void BitcoinGUI::createMenuBar() file->addAction(signMessageAction); file->addAction(verifyMessageAction); file->addSeparator(); + file->addAction(usedSendingAddressesAction); + file->addAction(usedReceivingAddressesAction); + file->addSeparator(); file->addAction(quitAction); QMenu *settings = appMenuBar->addMenu(tr("&Settings")); @@ -317,7 +318,6 @@ void BitcoinGUI::createToolBars() toolbar->addAction(sendCoinsAction); toolbar->addAction(receiveCoinsAction); toolbar->addAction(historyAction); - toolbar->addAction(addressBookAction); } void BitcoinGUI::setClientModel(ClientModel *clientModel) @@ -457,12 +457,6 @@ void BitcoinGUI::gotoHistoryPage() if (walletFrame) walletFrame->gotoHistoryPage(); } -void BitcoinGUI::gotoAddressBookPage() -{ - addressBookAction->setChecked(true); - if (walletFrame) walletFrame->gotoAddressBookPage(); -} - void BitcoinGUI::gotoReceiveCoinsPage() { receiveCoinsAction->setChecked(true); diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index e5a92fed93..5710b827ad 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -13,7 +13,6 @@ class WalletModel; class WalletStack; class TransactionView; class OverviewPage; -class AddressBookPage; class SendCoinsDialog; class SendCoinsRecipient; class SignVerifyMessageDialog; @@ -83,7 +82,8 @@ private: QAction *historyAction; QAction *quitAction; QAction *sendCoinsAction; - QAction *addressBookAction; + QAction *usedSendingAddressesAction; + QAction *usedReceivingAddressesAction; QAction *signMessageAction; QAction *verifyMessageAction; QAction *aboutAction; @@ -156,8 +156,6 @@ private slots: void gotoOverviewPage(); /** Switch to history (transactions) page */ void gotoHistoryPage(); - /** Switch to address book page */ - void gotoAddressBookPage(); /** Switch to receive coins page */ void gotoReceiveCoinsPage(); /** Switch to send coins page */ diff --git a/src/qt/forms/addressbookpage.ui b/src/qt/forms/addressbookpage.ui index a2a7da34dd..836d61024b 100644 --- a/src/qt/forms/addressbookpage.ui +++ b/src/qt/forms/addressbookpage.ui @@ -11,7 +11,7 @@ - Address Book + @@ -82,17 +82,6 @@ - - - - Show &QR Code - - - - :/icons/qrcode:/icons/qrcode - - - diff --git a/src/qt/forms/receivecoinsdialog.ui b/src/qt/forms/receivecoinsdialog.ui new file mode 100644 index 0000000000..a5946883bd --- /dev/null +++ b/src/qt/forms/receivecoinsdialog.ui @@ -0,0 +1,164 @@ + + + ReceiveCoinsDialog + + + + 0 + 0 + 776 + 343 + + + + Form + + + + + + QFormLayout::AllNonFixedFieldsGrow + + + + + &Amount: + + + reqAmount + + + + + + + + 80 + 0 + + + + + + + + &Label: + + + reqLabel + + + + + + + + + + &Message: + + + reqMessage + + + + + + + + + + + + + + + + + R&euse an existing receiving address + + + + + + + Use this form to request payments. All fields are optional. + + + + + + + + + + + + 0 + 0 + + + + Remove all transaction fields + + + Clear + + + + :/icons/remove:/icons/remove + + + 300 + + + false + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 150 + 0 + + + + &Request payment + + + + :/icons/receiving_addresses:/icons/receiving_addresses + + + + + + + + + + BitcoinAmountField + QLineEdit +
bitcoinamountfield.h
+
+
+ + + + +
diff --git a/src/qt/forms/qrcodedialog.ui b/src/qt/forms/receiverequestdialog.ui similarity index 64% rename from src/qt/forms/qrcodedialog.ui rename to src/qt/forms/receiverequestdialog.ui index 1cec9066f8..7430b34d0c 100644 --- a/src/qt/forms/qrcodedialog.ui +++ b/src/qt/forms/receiverequestdialog.ui @@ -1,17 +1,17 @@ - QRCodeDialog - + ReceiveRequestDialog + 0 0 - 340 - 530 + 487 + 597 - QR Code Dialog + Request coins @@ -39,6 +39,37 @@
+ + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + &Save Image... + + + + + + + + + Bitcoin URI: + + + @@ -61,25 +92,22 @@ + + + + Payment information: + + + - - - - true - - - Request Payment - - - QFormLayout::AllNonFixedFieldsGrow - + Label: @@ -95,10 +123,17 @@ - - + + + + true + + + true + + - + Message: @@ -114,10 +149,17 @@ - - + + + + true + + + true + + - + @@ -139,10 +181,10 @@ - - + + - false + true @@ -150,29 +192,31 @@ 0 + + true + - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - + + - &Save As... + Address: + + + Qt::PlainText + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + reqAddress + + + + + + + true @@ -186,27 +230,10 @@ BitcoinAmountField - QLineEdit + QWidget
bitcoinamountfield.h
- - - chkReqPayment - clicked(bool) - lnReqAmount - setEnabled(bool) - - - 92 - 285 - - - 98 - 311 - - - - + diff --git a/src/qt/receivecoinsdialog.cpp b/src/qt/receivecoinsdialog.cpp new file mode 100644 index 0000000000..9e81c2cf7b --- /dev/null +++ b/src/qt/receivecoinsdialog.cpp @@ -0,0 +1,105 @@ +#include "receivecoinsdialog.h" +#include "ui_receivecoinsdialog.h" + +#include "walletmodel.h" +#include "bitcoinunits.h" +#include "addressbookpage.h" +#include "optionsmodel.h" +#include "guiutil.h" +#include "receiverequestdialog.h" +#include "addresstablemodel.h" + +#include +#include +#include + +ReceiveCoinsDialog::ReceiveCoinsDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::ReceiveCoinsDialog), + model(0) +{ + ui->setupUi(this); + +#ifdef Q_OS_MAC // Icons on push buttons are very uncommon on Mac + ui->clearButton->setIcon(QIcon()); + ui->receiveButton->setIcon(QIcon()); +#endif + connect(ui->clearButton, SIGNAL(clicked()), this, SLOT(clear())); +} + +void ReceiveCoinsDialog::setModel(WalletModel *model) +{ + this->model = model; + + if(model && model->getOptionsModel()) + { + connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit())); + updateDisplayUnit(); + } +} + +ReceiveCoinsDialog::~ReceiveCoinsDialog() +{ + delete ui; +} + +void ReceiveCoinsDialog::clear() +{ + ui->reqAmount->clear(); + ui->reqLabel->setText(""); + ui->reqMessage->setText(""); + ui->reuseAddress->setChecked(false); + updateDisplayUnit(); +} + +void ReceiveCoinsDialog::reject() +{ + clear(); +} + +void ReceiveCoinsDialog::accept() +{ + clear(); +} + +void ReceiveCoinsDialog::updateDisplayUnit() +{ + if(model && model->getOptionsModel()) + { + ui->reqAmount->setDisplayUnit(model->getOptionsModel()->getDisplayUnit()); + } +} + +void ReceiveCoinsDialog::on_receiveButton_clicked() +{ + if(!model || !model->getOptionsModel() || !model->getAddressTableModel()) + return; + + QString address; + QString label = ui->reqLabel->text(); + if(ui->reuseAddress->isChecked()) + { + /* Choose existing receiving address */ + AddressBookPage dlg(AddressBookPage::ForSelection, AddressBookPage::ReceivingTab, this); + dlg.setModel(model->getAddressTableModel()); + if(dlg.exec()) + { + address = dlg.getReturnValue(); + if(label.isEmpty()) /* If no label provided, use the previously used label */ + { + label = model->getAddressTableModel()->labelForAddress(address); + } + } else { + return; + } + } else { + /* Generate new receiving address */ + address = model->getAddressTableModel()->addRow(AddressTableModel::Receive, label, ""); + } + ReceiveRequestDialog *dialog = new ReceiveRequestDialog(address, label, + ui->reqAmount->value(), ui->reqMessage->text(), this); + dialog->setModel(model->getOptionsModel()); + dialog->setAttribute(Qt::WA_DeleteOnClose); + dialog->show(); + clear(); +} diff --git a/src/qt/receivecoinsdialog.h b/src/qt/receivecoinsdialog.h new file mode 100644 index 0000000000..8d12e55afe --- /dev/null +++ b/src/qt/receivecoinsdialog.h @@ -0,0 +1,38 @@ +#ifndef RECEIVECOINSDIALOG_H +#define RECEIVECOINSDIALOG_H + +#include +#include + +namespace Ui { + class ReceiveCoinsDialog; +} +class WalletModel; +class OptionsModel; + +/** Dialog for requesting payment of bitcoins */ +class ReceiveCoinsDialog : public QDialog +{ + Q_OBJECT + +public: + explicit ReceiveCoinsDialog(QWidget *parent = 0); + ~ReceiveCoinsDialog(); + + void setModel(WalletModel *model); + +public slots: + void clear(); + void reject(); + void accept(); + +private: + Ui::ReceiveCoinsDialog *ui; + WalletModel *model; + +private slots: + void on_receiveButton_clicked(); + void updateDisplayUnit(); +}; + +#endif // RECEIVECOINSDIALOG_H diff --git a/src/qt/qrcodedialog.cpp b/src/qt/receiverequestdialog.cpp similarity index 60% rename from src/qt/qrcodedialog.cpp rename to src/qt/receiverequestdialog.cpp index 6ddcaaf5d9..b40cda9b32 100644 --- a/src/qt/qrcodedialog.cpp +++ b/src/qt/receiverequestdialog.cpp @@ -1,5 +1,5 @@ -#include "qrcodedialog.h" -#include "ui_qrcodedialog.h" +#include "receiverequestdialog.h" +#include "ui_receiverequestdialog.h" #include "bitcoinunits.h" #include "guiconstants.h" @@ -11,35 +11,46 @@ #include #endif -#include +#include "bitcoin-config.h" /* for USE_QRCODE */ -QRCodeDialog::QRCodeDialog(const QString &addr, const QString &label, bool enableReq, QWidget *parent) : +#ifdef USE_QRCODE +#include +#endif + +ReceiveRequestDialog::ReceiveRequestDialog(const QString &addr, const QString &label, quint64 amount, const QString &message, QWidget *parent) : QDialog(parent), - ui(new Ui::QRCodeDialog), + ui(new Ui::ReceiveRequestDialog), model(0), address(addr) { ui->setupUi(this); - setWindowTitle(QString("%1").arg(address)); - - ui->chkReqPayment->setVisible(enableReq); - ui->lblAmount->setVisible(enableReq); - ui->lnReqAmount->setVisible(enableReq); + QString target = label; + if(target.isEmpty()) + target = addr; + setWindowTitle(tr("Request payment to %1").arg(target)); + ui->lnAddress->setText(addr); + if(amount) + ui->lnReqAmount->setValue(amount); + ui->lnReqAmount->setReadOnly(true); ui->lnLabel->setText(label); + ui->lnMessage->setText(message); - ui->btnSaveAs->setEnabled(false); +#ifndef USE_QRCODE + ui->btnSaveAs->setVisible(false); + ui->lblQRCode->setVisible(false); +#endif genCode(); } -QRCodeDialog::~QRCodeDialog() +ReceiveRequestDialog::~ReceiveRequestDialog() { delete ui; } -void QRCodeDialog::setModel(OptionsModel *model) +void ReceiveRequestDialog::setModel(OptionsModel *model) { this->model = model; @@ -50,10 +61,12 @@ void QRCodeDialog::setModel(OptionsModel *model) updateDisplayUnit(); } -void QRCodeDialog::genCode() +void ReceiveRequestDialog::genCode() { QString uri = getURI(); - + ui->btnSaveAs->setEnabled(false); + ui->outUri->setPlainText(uri); +#ifdef USE_QRCODE if (uri != "") { ui->lblQRCode->setText(""); @@ -78,32 +91,21 @@ void QRCodeDialog::genCode() QRcode_free(code); ui->lblQRCode->setPixmap(QPixmap::fromImage(myImage).scaled(300, 300)); - - ui->outUri->setPlainText(uri); + ui->btnSaveAs->setEnabled(true); } +#endif } -QString QRCodeDialog::getURI() +QString ReceiveRequestDialog::getURI() { QString ret = QString("bitcoin:%1").arg(address); int paramCount = 0; - ui->outUri->clear(); - - if (ui->chkReqPayment->isChecked()) + if (ui->lnReqAmount->validate()) { - if (ui->lnReqAmount->validate()) - { - // 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(""); - } + // 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++; } if (!ui->lnLabel->text().isEmpty()) @@ -120,50 +122,41 @@ QString QRCodeDialog::getURI() paramCount++; } - // limit URI length to prevent a DoS against the QR-Code dialog + // limit URI length 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() +void ReceiveRequestDialog::on_lnReqAmount_textChanged() { genCode(); } -void QRCodeDialog::on_lnLabel_textChanged() +void ReceiveRequestDialog::on_lnLabel_textChanged() { genCode(); } -void QRCodeDialog::on_lnMessage_textChanged() +void ReceiveRequestDialog::on_lnMessage_textChanged() { genCode(); } -void QRCodeDialog::on_btnSaveAs_clicked() +void ReceiveRequestDialog::on_btnSaveAs_clicked() { +#ifdef USE_QRCODE QString fn = GUIUtil::getSaveFileName(this, tr("Save QR Code"), QString(), tr("PNG Images (*.png)")); if (!fn.isEmpty()) myImage.scaled(EXPORT_IMAGE_SIZE, EXPORT_IMAGE_SIZE).save(fn); +#endif } -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() +void ReceiveRequestDialog::updateDisplayUnit() { if (model) { diff --git a/src/qt/qrcodedialog.h b/src/qt/receiverequestdialog.h similarity index 65% rename from src/qt/qrcodedialog.h rename to src/qt/receiverequestdialog.h index c55c34bce6..37a3fa22d6 100644 --- a/src/qt/qrcodedialog.h +++ b/src/qt/receiverequestdialog.h @@ -5,17 +5,17 @@ #include namespace Ui { - class QRCodeDialog; + class ReceiveRequestDialog; } class OptionsModel; -class QRCodeDialog : public QDialog +class ReceiveRequestDialog : public QDialog { Q_OBJECT public: - explicit QRCodeDialog(const QString &addr, const QString &label, bool enableReq, QWidget *parent = 0); - ~QRCodeDialog(); + explicit ReceiveRequestDialog(const QString &addr, const QString &label, quint64 amount, const QString &message, QWidget *parent = 0); + ~ReceiveRequestDialog(); void setModel(OptionsModel *model); @@ -24,12 +24,11 @@ private slots: void on_lnLabel_textChanged(); void on_lnMessage_textChanged(); void on_btnSaveAs_clicked(); - void on_chkReqPayment_toggled(bool fChecked); void updateDisplayUnit(); private: - Ui::QRCodeDialog *ui; + Ui::ReceiveRequestDialog *ui; OptionsModel *model; QString address; QImage myImage; diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp index 188b8860a9..2d42ecb568 100644 --- a/src/qt/sendcoinsentry.cpp +++ b/src/qt/sendcoinsentry.cpp @@ -49,7 +49,7 @@ void SendCoinsEntry::on_addressBookButton_clicked() { if(!model) return; - AddressBookPage dlg(AddressBookPage::ForSending, AddressBookPage::SendingTab, this); + AddressBookPage dlg(AddressBookPage::ForSelection, AddressBookPage::SendingTab, this); dlg.setModel(model->getAddressTableModel()); if(dlg.exec()) { diff --git a/src/qt/signverifymessagedialog.cpp b/src/qt/signverifymessagedialog.cpp index 1e9c84fe1a..ff3d00b326 100644 --- a/src/qt/signverifymessagedialog.cpp +++ b/src/qt/signverifymessagedialog.cpp @@ -86,7 +86,7 @@ void SignVerifyMessageDialog::on_addressBookButton_SM_clicked() { if (model && model->getAddressTableModel()) { - AddressBookPage dlg(AddressBookPage::ForSending, AddressBookPage::ReceivingTab, this); + AddressBookPage dlg(AddressBookPage::ForSelection, AddressBookPage::ReceivingTab, this); dlg.setModel(model->getAddressTableModel()); if (dlg.exec()) { @@ -178,7 +178,7 @@ void SignVerifyMessageDialog::on_addressBookButton_VM_clicked() { if (model && model->getAddressTableModel()) { - AddressBookPage dlg(AddressBookPage::ForSending, AddressBookPage::SendingTab, this); + AddressBookPage dlg(AddressBookPage::ForSelection, AddressBookPage::SendingTab, this); dlg.setModel(model->getAddressTableModel()); if (dlg.exec()) { diff --git a/src/qt/walletframe.cpp b/src/qt/walletframe.cpp index f754bd5e71..dd1d69ec3a 100644 --- a/src/qt/walletframe.cpp +++ b/src/qt/walletframe.cpp @@ -115,13 +115,6 @@ void WalletFrame::gotoHistoryPage() i.value()->gotoHistoryPage(); } -void WalletFrame::gotoAddressBookPage() -{ - QMap::const_iterator i; - for (i = mapWalletViews.constBegin(); i != mapWalletViews.constEnd(); ++i) - i.value()->gotoAddressBookPage(); -} - void WalletFrame::gotoReceiveCoinsPage() { QMap::const_iterator i; @@ -184,3 +177,17 @@ void WalletFrame::setEncryptionStatus() if (walletView) walletView->setEncryptionStatus(); } + +void WalletFrame::usedSendingAddresses() +{ + WalletView *walletView = (WalletView*)walletStack->currentWidget(); + if (walletView) + walletView->usedSendingAddresses(); +} + +void WalletFrame::usedReceivingAddresses() +{ + WalletView *walletView = (WalletView*)walletStack->currentWidget(); + if (walletView) + walletView->usedReceivingAddresses(); +} diff --git a/src/qt/walletframe.h b/src/qt/walletframe.h index 5011987963..89983b4aec 100644 --- a/src/qt/walletframe.h +++ b/src/qt/walletframe.h @@ -52,8 +52,6 @@ public slots: void gotoOverviewPage(); /** Switch to history (transactions) page */ void gotoHistoryPage(); - /** Switch to address book page */ - void gotoAddressBookPage(); /** Switch to receive coins page */ void gotoReceiveCoinsPage(); /** Switch to send coins page */ @@ -73,6 +71,11 @@ public slots: /** Ask for passphrase to unlock wallet temporarily */ void unlockWallet(); + /** Show used sending addresses */ + void usedSendingAddresses(); + /** Show used receiving addresses */ + void usedReceivingAddresses(); + /** Set the encryption status as shown in the UI. @param[in] status current encryption status @see WalletModel::EncryptionStatus diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp index d7cef971ed..1b80ae34ed 100644 --- a/src/qt/walletview.cpp +++ b/src/qt/walletview.cpp @@ -9,6 +9,7 @@ #include "transactiontablemodel.h" #include "addressbookpage.h" #include "sendcoinsdialog.h" +#include "receivecoinsdialog.h" #include "signverifymessagedialog.h" #include "clientmodel.h" #include "walletmodel.h" @@ -53,13 +54,11 @@ WalletView::WalletView(QWidget *parent): vbox->addLayout(hbox_buttons); transactionsPage->setLayout(vbox); - addressBookPage = new AddressBookPage(AddressBookPage::ForEditing, AddressBookPage::SendingTab); - receiveCoinsPage = new AddressBookPage(AddressBookPage::ForEditing, AddressBookPage::ReceivingTab); - sendCoinsPage = new SendCoinsDialog(); + receiveCoinsPage = new ReceiveCoinsDialog(gui); + sendCoinsPage = new SendCoinsDialog(gui); addWidget(overviewPage); addWidget(transactionsPage); - addWidget(addressBookPage); addWidget(receiveCoinsPage); addWidget(sendCoinsPage); @@ -69,10 +68,6 @@ WalletView::WalletView(QWidget *parent): // Double-clicking on a transaction on the transaction history page shows details connect(transactionView, SIGNAL(doubleClicked(QModelIndex)), transactionView, SLOT(showDetails())); - // Clicking on "Send Coins" in the address book sends you to the send coins tab - connect(addressBookPage, SIGNAL(sendCoins(QString)), this, SLOT(gotoSendCoinsPage(QString))); - // Clicking on "Verify Message" in the address book opens the verify message tab in the Sign/Verify Message dialog - connect(addressBookPage, SIGNAL(verifyMessage(QString)), this, SLOT(gotoVerifyMessageTab(QString))); // Clicking on "Sign Message" in the receive coins page opens the sign message tab in the Sign/Verify Message dialog connect(receiveCoinsPage, SIGNAL(signMessage(QString)), this, SLOT(gotoSignMessageTab(QString))); // Clicking on "Export" allows to export the transaction list @@ -98,8 +93,6 @@ void WalletView::setClientModel(ClientModel *clientModel) if (clientModel) { overviewPage->setClientModel(clientModel); - addressBookPage->setOptionsModel(clientModel->getOptionsModel()); - receiveCoinsPage->setOptionsModel(clientModel->getOptionsModel()); } } @@ -114,8 +107,7 @@ void WalletView::setWalletModel(WalletModel *walletModel) // Put transaction list in tabs transactionView->setModel(walletModel); overviewPage->setWalletModel(walletModel); - addressBookPage->setModel(walletModel->getAddressTableModel()); - receiveCoinsPage->setModel(walletModel->getAddressTableModel()); + receiveCoinsPage->setModel(walletModel); sendCoinsPage->setModel(walletModel); setEncryptionStatus(); @@ -156,11 +148,6 @@ void WalletView::gotoHistoryPage() setCurrentWidget(transactionsPage); } -void WalletView::gotoAddressBookPage() -{ - setCurrentWidget(addressBookPage); -} - void WalletView::gotoReceiveCoinsPage() { setCurrentWidget(receiveCoinsPage); @@ -270,3 +257,23 @@ void WalletView::unlockWallet() dlg.exec(); } } + +void WalletView::usedSendingAddresses() +{ + if(!walletModel) + return; + AddressBookPage *dlg = new AddressBookPage(AddressBookPage::ForEditing, AddressBookPage::SendingTab, this); + dlg->setModel(walletModel->getAddressTableModel()); + dlg->setAttribute(Qt::WA_DeleteOnClose); + dlg->show(); +} + +void WalletView::usedReceivingAddresses() +{ + if(!walletModel) + return; + AddressBookPage *dlg = new AddressBookPage(AddressBookPage::ForEditing, AddressBookPage::ReceivingTab, this); + dlg->setModel(walletModel->getAddressTableModel()); + dlg->setAttribute(Qt::WA_DeleteOnClose); + dlg->show(); +} diff --git a/src/qt/walletview.h b/src/qt/walletview.h index e3ff253d3c..54451d744a 100644 --- a/src/qt/walletview.h +++ b/src/qt/walletview.h @@ -14,8 +14,8 @@ class ClientModel; class WalletModel; class TransactionView; class OverviewPage; -class AddressBookPage; class SendCoinsDialog; +class ReceiveCoinsDialog; class SendCoinsRecipient; class SignVerifyMessageDialog; class RPCConsole; @@ -61,8 +61,7 @@ private: OverviewPage *overviewPage; QWidget *transactionsPage; - AddressBookPage *addressBookPage; - AddressBookPage *receiveCoinsPage; + ReceiveCoinsDialog *receiveCoinsPage; SendCoinsDialog *sendCoinsPage; TransactionView *transactionView; @@ -72,8 +71,6 @@ public slots: void gotoOverviewPage(); /** Switch to history (transactions) page */ void gotoHistoryPage(); - /** Switch to address book page */ - void gotoAddressBookPage(); /** Switch to receive coins page */ void gotoReceiveCoinsPage(); /** Switch to send coins page */ @@ -98,6 +95,11 @@ public slots: /** Ask for passphrase to unlock wallet temporarily */ void unlockWallet(); + /** Show used sending addresses */ + void usedSendingAddresses(); + /** Show used receiving addresses */ + void usedReceivingAddresses(); + void setEncryptionStatus(); signals: From 864a6f790ee80a4acc56189cdc1897c9a3ed6998 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 18 Oct 2013 11:23:48 +0200 Subject: [PATCH 2/8] qt: remove verify/send message and send coins from address book These no longer make sense in the new workflow. It's less clicks to reach sign/verify message from the menu. And sending from the address book is one kind of automatic address reuse we're trying to avoid. --- src/qt/addressbookpage.cpp | 62 --------------------------------- src/qt/addressbookpage.h | 8 ----- src/qt/forms/addressbookpage.ui | 28 --------------- 3 files changed, 98 deletions(-) diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp index c9718c37bc..7fbdf2e9c5 100644 --- a/src/qt/addressbookpage.cpp +++ b/src/qt/addressbookpage.cpp @@ -31,8 +31,6 @@ AddressBookPage::AddressBookPage(Mode mode, Tabs tab, QWidget *parent) : ui->newAddress->setIcon(QIcon()); ui->copyAddress->setIcon(QIcon()); ui->deleteAddress->setIcon(QIcon()); - ui->verifyMessage->setIcon(QIcon()); - ui->signMessage->setIcon(QIcon()); ui->exportButton->setIcon(QIcon()); #endif @@ -62,12 +60,10 @@ AddressBookPage::AddressBookPage(Mode mode, Tabs tab, QWidget *parent) : case SendingTab: ui->labelExplanation->setText(tr("These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.")); ui->deleteAddress->setVisible(true); - ui->signMessage->setVisible(false); break; case ReceivingTab: ui->labelExplanation->setText(tr("These are your Bitcoin addresses for receiving payments. It is recommended to use a new receiving address for each transaction.")); ui->deleteAddress->setVisible(false); - ui->signMessage->setVisible(true); break; } @@ -75,9 +71,6 @@ AddressBookPage::AddressBookPage(Mode mode, Tabs tab, QWidget *parent) : QAction *copyAddressAction = new QAction(ui->copyAddress->text(), this); QAction *copyLabelAction = new QAction(tr("Copy &Label"), this); QAction *editAction = new QAction(tr("&Edit"), this); - QAction *sendCoinsAction = new QAction(tr("Send &Coins"), this); - QAction *signMessageAction = new QAction(ui->signMessage->text(), this); - QAction *verifyMessageAction = new QAction(ui->verifyMessage->text(), this); deleteAction = new QAction(ui->deleteAddress->text(), this); // Build context menu @@ -88,21 +81,12 @@ AddressBookPage::AddressBookPage(Mode mode, Tabs tab, QWidget *parent) : if(tab == SendingTab) contextMenu->addAction(deleteAction); contextMenu->addSeparator(); - if(tab == SendingTab) - contextMenu->addAction(sendCoinsAction); - if(tab == ReceivingTab) - contextMenu->addAction(signMessageAction); - else if(tab == SendingTab) - contextMenu->addAction(verifyMessageAction); // Connect signals for context menu actions connect(copyAddressAction, SIGNAL(triggered()), this, SLOT(on_copyAddress_clicked())); connect(copyLabelAction, SIGNAL(triggered()), this, SLOT(onCopyLabelAction())); connect(editAction, SIGNAL(triggered()), this, SLOT(onEditAction())); connect(deleteAction, SIGNAL(triggered()), this, SLOT(on_deleteAddress_clicked())); - connect(sendCoinsAction, SIGNAL(triggered()), this, SLOT(onSendCoinsAction())); - connect(signMessageAction, SIGNAL(triggered()), this, SLOT(on_signMessage_clicked())); - connect(verifyMessageAction, SIGNAL(triggered()), this, SLOT(on_verifyMessage_clicked())); connect(ui->tableView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextualMenu(QPoint))); @@ -193,42 +177,6 @@ void AddressBookPage::onEditAction() dlg.exec(); } -void AddressBookPage::on_signMessage_clicked() -{ - QTableView *table = ui->tableView; - QModelIndexList indexes = table->selectionModel()->selectedRows(AddressTableModel::Address); - - foreach (QModelIndex index, indexes) - { - QString address = index.data().toString(); - emit signMessage(address); - } -} - -void AddressBookPage::on_verifyMessage_clicked() -{ - QTableView *table = ui->tableView; - QModelIndexList indexes = table->selectionModel()->selectedRows(AddressTableModel::Address); - - foreach (QModelIndex index, indexes) - { - QString address = index.data().toString(); - emit verifyMessage(address); - } -} - -void AddressBookPage::onSendCoinsAction() -{ - QTableView *table = ui->tableView; - QModelIndexList indexes = table->selectionModel()->selectedRows(AddressTableModel::Address); - - foreach (QModelIndex index, indexes) - { - QString address = index.data().toString(); - emit sendCoins(address); - } -} - void AddressBookPage::on_newAddress_clicked() { if(!model) @@ -274,20 +222,12 @@ void AddressBookPage::selectionChanged() ui->deleteAddress->setEnabled(true); ui->deleteAddress->setVisible(true); deleteAction->setEnabled(true); - ui->signMessage->setEnabled(false); - ui->signMessage->setVisible(false); - ui->verifyMessage->setEnabled(true); - ui->verifyMessage->setVisible(true); break; case ReceivingTab: // Deleting receiving addresses, however, is not allowed ui->deleteAddress->setEnabled(false); ui->deleteAddress->setVisible(false); deleteAction->setEnabled(false); - ui->signMessage->setEnabled(true); - ui->signMessage->setVisible(true); - ui->verifyMessage->setEnabled(false); - ui->verifyMessage->setVisible(false); break; } ui->copyAddress->setEnabled(true); @@ -296,8 +236,6 @@ void AddressBookPage::selectionChanged() { ui->deleteAddress->setEnabled(false); ui->copyAddress->setEnabled(false); - ui->signMessage->setEnabled(false); - ui->verifyMessage->setEnabled(false); } } diff --git a/src/qt/addressbookpage.h b/src/qt/addressbookpage.h index 70ff3984be..9255e58144 100644 --- a/src/qt/addressbookpage.h +++ b/src/qt/addressbookpage.h @@ -63,12 +63,6 @@ private slots: void on_newAddress_clicked(); /** Copy address of currently selected address entry to clipboard */ void on_copyAddress_clicked(); - /** Open the sign message tab in the Sign/Verify Message dialog with currently selected address */ - void on_signMessage_clicked(); - /** Open the verify message tab in the Sign/Verify Message dialog with currently selected address */ - void on_verifyMessage_clicked(); - /** Open send coins dialog for currently selected address (no button) */ - void onSendCoinsAction(); /** Copy label of currently selected address entry to clipboard (no button) */ void onCopyLabelAction(); /** Edit currently selected address entry (no button) */ @@ -84,8 +78,6 @@ private slots: void selectNewAddress(const QModelIndex &parent, int begin, int /*end*/); signals: - void signMessage(QString addr); - void verifyMessage(QString addr); void sendCoins(QString addr); }; diff --git a/src/qt/forms/addressbookpage.ui b/src/qt/forms/addressbookpage.ui index 836d61024b..9edaf74023 100644 --- a/src/qt/forms/addressbookpage.ui +++ b/src/qt/forms/addressbookpage.ui @@ -82,34 +82,6 @@
- - - - Sign a message to prove you own a Bitcoin address - - - Sign &Message - - - - :/icons/edit:/icons/edit - - - - - - - Verify a message to ensure it was signed with a specified Bitcoin address - - - &Verify Message - - - - :/icons/transaction_0:/icons/transaction_0 - - - From 82095923bb71a670aa67ad15987bb6d4d7726abe Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 18 Oct 2013 13:08:30 +0200 Subject: [PATCH 3/8] qt: allow dragging, copying and saving QR code Add context menu and drag handling to QR code widget. --- src/qt/forms/receiverequestdialog.ui | 7 +++- src/qt/receiverequestdialog.cpp | 59 +++++++++++++++++++++++----- src/qt/receiverequestdialog.h | 22 ++++++++++- 3 files changed, 75 insertions(+), 13 deletions(-) diff --git a/src/qt/forms/receiverequestdialog.ui b/src/qt/forms/receiverequestdialog.ui index 7430b34d0c..4f53dc19b8 100644 --- a/src/qt/forms/receiverequestdialog.ui +++ b/src/qt/forms/receiverequestdialog.ui @@ -15,7 +15,7 @@ - + 0 @@ -233,6 +233,11 @@ QWidget
bitcoinamountfield.h
+ + QRImageWidget + QLabel +
receiverequestdialog.h
+
diff --git a/src/qt/receiverequestdialog.cpp b/src/qt/receiverequestdialog.cpp index b40cda9b32..dd4f5f16f4 100644 --- a/src/qt/receiverequestdialog.cpp +++ b/src/qt/receiverequestdialog.cpp @@ -7,6 +7,7 @@ #include "optionsmodel.h" #include +#include #if QT_VERSION < 0x050000 #include #endif @@ -17,6 +18,51 @@ #include #endif +QRImageWidget::QRImageWidget(QWidget *parent): + QLabel(parent) +{ + setContextMenuPolicy(Qt::ActionsContextMenu); + + QAction *saveImageAction = new QAction(tr("&Save Image..."), this); + connect(saveImageAction, SIGNAL(triggered()), this, SLOT(saveImage())); + addAction(saveImageAction); + QAction *copyImageAction = new QAction(tr("&Copy Image"), this); + connect(copyImageAction, SIGNAL(triggered()), this, SLOT(copyImage())); + addAction(copyImageAction); +} + +QImage QRImageWidget::exportImage() +{ + return pixmap()->toImage().scaled(EXPORT_IMAGE_SIZE, EXPORT_IMAGE_SIZE); +} + +void QRImageWidget::mousePressEvent(QMouseEvent *event) +{ + if(event->button() == Qt::LeftButton) + { + QMimeData *mimeData = new QMimeData; + mimeData->setImageData(exportImage()); + + QDrag *drag = new QDrag(this); + drag->setMimeData(mimeData); + drag->exec(); + } +} + +void QRImageWidget::saveImage() +{ + QString fn = GUIUtil::getSaveFileName(this, tr("Save QR Code"), QString(), tr("PNG Images (*.png)")); + if (!fn.isEmpty()) + { + exportImage().save(fn); + } +} + +void QRImageWidget::copyImage() +{ + QApplication::clipboard()->setImage(exportImage()); +} + ReceiveRequestDialog::ReceiveRequestDialog(const QString &addr, const QString &label, quint64 amount, const QString &message, QWidget *parent) : QDialog(parent), ui(new Ui::ReceiveRequestDialog), @@ -42,6 +88,8 @@ ReceiveRequestDialog::ReceiveRequestDialog(const QString &addr, const QString &l ui->lblQRCode->setVisible(false); #endif + connect(ui->btnSaveAs, SIGNAL(clicked()), ui->lblQRCode, SLOT(saveImage())); + genCode(); } @@ -77,7 +125,7 @@ void ReceiveRequestDialog::genCode() ui->lblQRCode->setText(tr("Error encoding URI into QR Code.")); return; } - myImage = QImage(code->width + 8, code->width + 8, QImage::Format_RGB32); + QImage myImage = QImage(code->width + 8, code->width + 8, QImage::Format_RGB32); myImage.fill(0xffffff); unsigned char *p = code->data; for (int y = 0; y < code->width; y++) @@ -147,15 +195,6 @@ void ReceiveRequestDialog::on_lnMessage_textChanged() genCode(); } -void ReceiveRequestDialog::on_btnSaveAs_clicked() -{ -#ifdef USE_QRCODE - QString fn = GUIUtil::getSaveFileName(this, tr("Save QR Code"), QString(), tr("PNG Images (*.png)")); - if (!fn.isEmpty()) - myImage.scaled(EXPORT_IMAGE_SIZE, EXPORT_IMAGE_SIZE).save(fn); -#endif -} - void ReceiveRequestDialog::updateDisplayUnit() { if (model) diff --git a/src/qt/receiverequestdialog.h b/src/qt/receiverequestdialog.h index 37a3fa22d6..e560a24ff1 100644 --- a/src/qt/receiverequestdialog.h +++ b/src/qt/receiverequestdialog.h @@ -3,12 +3,32 @@ #include #include +#include namespace Ui { class ReceiveRequestDialog; } class OptionsModel; +/* Label widget for QR code. This image can be dragged, dropped, copied and saved + * to disk. + */ +class QRImageWidget : public QLabel +{ + Q_OBJECT + +public: + explicit QRImageWidget(QWidget *parent = 0); + QImage exportImage(); + +public slots: + void saveImage(); + void copyImage(); + +protected: + virtual void mousePressEvent(QMouseEvent *event); +}; + class ReceiveRequestDialog : public QDialog { Q_OBJECT @@ -23,7 +43,6 @@ private slots: void on_lnReqAmount_textChanged(); void on_lnLabel_textChanged(); void on_lnMessage_textChanged(); - void on_btnSaveAs_clicked(); void updateDisplayUnit(); @@ -31,7 +50,6 @@ private: Ui::ReceiveRequestDialog *ui; OptionsModel *model; QString address; - QImage myImage; void genCode(); QString getURI(); From 03535acd053fc0597a9e1fd76c5c7b1f54f5c1df Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 18 Oct 2013 13:44:27 +0200 Subject: [PATCH 4/8] qt: add message field to SendCoinsRecipient Also update URI parsing to fill in this field. Note that the message is not currently used in any way with the client. It should be stored with the transaction. --- src/qt/guiutil.cpp | 5 +++++ src/qt/test/uritests.cpp | 3 +-- src/qt/walletmodel.h | 5 ++++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index b65348548b..e7334e67cb 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -112,6 +112,11 @@ bool parseBitcoinURI(const QUrl &uri, SendCoinsRecipient *out) rv.label = i->second; fShouldReturnFalse = false; } + if (i->first == "message") + { + rv.message = i->second; + fShouldReturnFalse = false; + } else if (i->first == "amount") { if(!i->second.isEmpty()) diff --git a/src/qt/test/uritests.cpp b/src/qt/test/uritests.cpp index 802d74719e..df4df3154b 100644 --- a/src/qt/test/uritests.cpp +++ b/src/qt/test/uritests.cpp @@ -50,9 +50,8 @@ void URITests::uriTests() QVERIFY(rv.address == QString("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W")); QVERIFY(rv.label == QString()); - // We currently don't implement the message parameter (ok, yea, we break spec...) uri.setUrl(QString("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?req-message=Wikipedia Example Address")); - QVERIFY(!GUIUtil::parseBitcoinURI(uri, &rv)); + QVERIFY(GUIUtil::parseBitcoinURI(uri, &rv)); uri.setUrl(QString("bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?amount=1,000&label=Wikipedia Example")); QVERIFY(!GUIUtil::parseBitcoinURI(uri, &rv)); diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h index 6abcdaf8cb..2e99eaddcb 100644 --- a/src/qt/walletmodel.h +++ b/src/qt/walletmodel.h @@ -21,11 +21,14 @@ QT_END_NAMESPACE class SendCoinsRecipient { public: - SendCoinsRecipient() : amount(0) { } + explicit SendCoinsRecipient() : amount(0) { } + explicit SendCoinsRecipient(const QString &addr, const QString &label, quint64 amount, const QString &message): + address(addr), label(label), amount(amount), message(message) {} QString address; QString label; qint64 amount; + QString message; // If from a payment request, paymentRequest.IsInitialized() will be true PaymentRequestPlus paymentRequest; From 8a7f37c7972504d25225c96f225503c329aaf6fa Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 18 Oct 2013 13:45:11 +0200 Subject: [PATCH 5/8] qt: use SendCoinsRecipient for payment request information This brings some symmetry into the design by using the same object both for incoming URIs that are parsed as for outgoing URIs that are formatted. --- src/qt/receivecoinsdialog.cpp | 5 +++-- src/qt/receiverequestdialog.cpp | 21 +++++++++++---------- src/qt/receiverequestdialog.h | 6 ++++-- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/qt/receivecoinsdialog.cpp b/src/qt/receivecoinsdialog.cpp index 9e81c2cf7b..fff678d0c6 100644 --- a/src/qt/receivecoinsdialog.cpp +++ b/src/qt/receivecoinsdialog.cpp @@ -96,8 +96,9 @@ void ReceiveCoinsDialog::on_receiveButton_clicked() /* Generate new receiving address */ address = model->getAddressTableModel()->addRow(AddressTableModel::Receive, label, ""); } - ReceiveRequestDialog *dialog = new ReceiveRequestDialog(address, label, - ui->reqAmount->value(), ui->reqMessage->text(), this); + SendCoinsRecipient info(address, label, + ui->reqAmount->value(), ui->reqMessage->text()); + ReceiveRequestDialog *dialog = new ReceiveRequestDialog(info, this); dialog->setModel(model->getOptionsModel()); dialog->setAttribute(Qt::WA_DeleteOnClose); dialog->show(); diff --git a/src/qt/receiverequestdialog.cpp b/src/qt/receiverequestdialog.cpp index dd4f5f16f4..861458f8d8 100644 --- a/src/qt/receiverequestdialog.cpp +++ b/src/qt/receiverequestdialog.cpp @@ -5,6 +5,7 @@ #include "guiconstants.h" #include "guiutil.h" #include "optionsmodel.h" +#include "walletmodel.h" #include #include @@ -63,25 +64,25 @@ void QRImageWidget::copyImage() QApplication::clipboard()->setImage(exportImage()); } -ReceiveRequestDialog::ReceiveRequestDialog(const QString &addr, const QString &label, quint64 amount, const QString &message, QWidget *parent) : +ReceiveRequestDialog::ReceiveRequestDialog(const SendCoinsRecipient &info, QWidget *parent) : QDialog(parent), ui(new Ui::ReceiveRequestDialog), model(0), - address(addr) + info(info) { ui->setupUi(this); - QString target = label; + QString target = info.label; if(target.isEmpty()) - target = addr; + target = info.address; setWindowTitle(tr("Request payment to %1").arg(target)); - ui->lnAddress->setText(addr); - if(amount) - ui->lnReqAmount->setValue(amount); + ui->lnAddress->setText(info.address); + if(info.amount) + ui->lnReqAmount->setValue(info.amount); ui->lnReqAmount->setReadOnly(true); - ui->lnLabel->setText(label); - ui->lnMessage->setText(message); + ui->lnLabel->setText(info.label); + ui->lnMessage->setText(info.message); #ifndef USE_QRCODE ui->btnSaveAs->setVisible(false); @@ -146,7 +147,7 @@ void ReceiveRequestDialog::genCode() QString ReceiveRequestDialog::getURI() { - QString ret = QString("bitcoin:%1").arg(address); + QString ret = QString("bitcoin:%1").arg(info.address); int paramCount = 0; if (ui->lnReqAmount->validate()) diff --git a/src/qt/receiverequestdialog.h b/src/qt/receiverequestdialog.h index e560a24ff1..bfe50bde77 100644 --- a/src/qt/receiverequestdialog.h +++ b/src/qt/receiverequestdialog.h @@ -1,6 +1,8 @@ #ifndef QRCODEDIALOG_H #define QRCODEDIALOG_H +#include "walletmodel.h" + #include #include #include @@ -34,7 +36,7 @@ class ReceiveRequestDialog : public QDialog Q_OBJECT public: - explicit ReceiveRequestDialog(const QString &addr, const QString &label, quint64 amount, const QString &message, QWidget *parent = 0); + explicit ReceiveRequestDialog(const SendCoinsRecipient &info, QWidget *parent = 0); ~ReceiveRequestDialog(); void setModel(OptionsModel *model); @@ -49,7 +51,7 @@ private slots: private: Ui::ReceiveRequestDialog *ui; OptionsModel *model; - QString address; + SendCoinsRecipient info; void genCode(); QString getURI(); From 786b066f037bf2d7ba7fe0df1a4e15b22ab65599 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 18 Oct 2013 14:03:17 +0200 Subject: [PATCH 6/8] qt: move bitcoin URI formatting to guiutil Follow the same pattern as the parseBitcoinURI function. --- src/qt/guiutil.cpp | 28 +++++++++++ src/qt/guiutil.h | 1 + src/qt/receiverequestdialog.cpp | 84 +++++++++++---------------------- 3 files changed, 56 insertions(+), 57 deletions(-) diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index e7334e67cb..9bb2fa7c99 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -153,6 +153,34 @@ bool parseBitcoinURI(QString uri, SendCoinsRecipient *out) return parseBitcoinURI(uriInstance, out); } +QString formatBitcoinURI(const SendCoinsRecipient &info) +{ + QString ret = QString("bitcoin:%1").arg(info.address); + int paramCount = 0; + + if (info.amount) + { + ret += QString("?amount=%1").arg(BitcoinUnits::format(BitcoinUnits::BTC, info.amount)); + paramCount++; + } + + if (!info.label.isEmpty()) + { + QString lbl(QUrl::toPercentEncoding(info.label)); + ret += QString("%1label=%2").arg(paramCount == 0 ? "?" : "&").arg(lbl); + paramCount++; + } + + if (!info.message.isEmpty()) + { + QString msg(QUrl::toPercentEncoding(info.message));; + ret += QString("%1message=%2").arg(paramCount == 0 ? "?" : "&").arg(msg); + paramCount++; + } + + return ret; +} + bool isDust(const QString& address, qint64 amount) { CTxDestination dest = CBitcoinAddress(address.toStdString()).Get(); diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h index 8472700f48..956f550989 100644 --- a/src/qt/guiutil.h +++ b/src/qt/guiutil.h @@ -35,6 +35,7 @@ namespace GUIUtil // See Bitcoin URI definition discussion here: https://bitcointalk.org/index.php?topic=33490.0 bool parseBitcoinURI(const QUrl &uri, SendCoinsRecipient *out); bool parseBitcoinURI(QString uri, SendCoinsRecipient *out); + QString formatBitcoinURI(const SendCoinsRecipient &info); // Returns true if given address+amount meets "dust" definition bool isDust(const QString& address, qint64 amount); diff --git a/src/qt/receiverequestdialog.cpp b/src/qt/receiverequestdialog.cpp index 861458f8d8..efbc6ebd70 100644 --- a/src/qt/receiverequestdialog.cpp +++ b/src/qt/receiverequestdialog.cpp @@ -112,75 +112,45 @@ void ReceiveRequestDialog::setModel(OptionsModel *model) void ReceiveRequestDialog::genCode() { - QString uri = getURI(); + QString uri = GUIUtil::formatBitcoinURI(info); ui->btnSaveAs->setEnabled(false); ui->outUri->setPlainText(uri); + #ifdef USE_QRCODE - if (uri != "") + ui->lblQRCode->setText(""); + if(!uri.isEmpty()) { - ui->lblQRCode->setText(""); - - QRcode *code = QRcode_encodeString(uri.toUtf8().constData(), 0, QR_ECLEVEL_L, QR_MODE_8, 1); - if (!code) + // limit URI length + if (uri.length() > MAX_URI_LENGTH) { - ui->lblQRCode->setText(tr("Error encoding URI into QR Code.")); - return; - } - QImage myImage = QImage(code->width + 8, code->width + 8, QImage::Format_RGB32); - myImage.fill(0xffffff); - unsigned char *p = code->data; - for (int y = 0; y < code->width; y++) - { - for (int x = 0; x < code->width; x++) + ui->lblQRCode->setText(tr("Resulting URI too long, try to reduce the text for label / message.")); + } else { + QRcode *code = QRcode_encodeString(uri.toUtf8().constData(), 0, QR_ECLEVEL_L, QR_MODE_8, 1); + if (!code) { - myImage.setPixel(x + 4, y + 4, ((*p & 1) ? 0x0 : 0xffffff)); - p++; + ui->lblQRCode->setText(tr("Error encoding URI into QR Code.")); + return; } - } - QRcode_free(code); + QImage myImage = QImage(code->width + 8, code->width + 8, QImage::Format_RGB32); + myImage.fill(0xffffff); + unsigned char *p = code->data; + for (int y = 0; y < code->width; y++) + { + for (int x = 0; x < code->width; x++) + { + myImage.setPixel(x + 4, y + 4, ((*p & 1) ? 0x0 : 0xffffff)); + p++; + } + } + QRcode_free(code); - ui->lblQRCode->setPixmap(QPixmap::fromImage(myImage).scaled(300, 300)); - ui->btnSaveAs->setEnabled(true); + ui->lblQRCode->setPixmap(QPixmap::fromImage(myImage).scaled(300, 300)); + ui->btnSaveAs->setEnabled(true); + } } #endif } -QString ReceiveRequestDialog::getURI() -{ - QString ret = QString("bitcoin:%1").arg(info.address); - int paramCount = 0; - - if (ui->lnReqAmount->validate()) - { - // 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++; - } - - if (!ui->lnLabel->text().isEmpty()) - { - QString lbl(QUrl::toPercentEncoding(ui->lnLabel->text())); - ret += QString("%1label=%2").arg(paramCount == 0 ? "?" : "&").arg(lbl); - paramCount++; - } - - if (!ui->lnMessage->text().isEmpty()) - { - QString msg(QUrl::toPercentEncoding(ui->lnMessage->text())); - ret += QString("%1message=%2").arg(paramCount == 0 ? "?" : "&").arg(msg); - paramCount++; - } - - // limit URI length - if (ret.length() > MAX_URI_LENGTH) - { - ui->lblQRCode->setText(tr("Resulting URI too long, try to reduce the text for label / message.")); - return QString(""); - } - - return ret; -} - void ReceiveRequestDialog::on_lnReqAmount_textChanged() { genCode(); From 33a2febf5de0c7bd73c0ea409584487bd9995643 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 18 Oct 2013 14:25:35 +0200 Subject: [PATCH 7/8] qt: show payment information in one text area Simplifies the dialog (makes it look less crowded) as well as the code and makes it possible to copy multiple fields at once. Also format bitcoin URI as URI, add copy button for URI. --- src/qt/forms/receiverequestdialog.ui | 209 +++++---------------------- src/qt/receivecoinsdialog.cpp | 3 +- src/qt/receiverequestdialog.cpp | 83 ++++++----- src/qt/receiverequestdialog.h | 12 +- 4 files changed, 86 insertions(+), 221 deletions(-) diff --git a/src/qt/forms/receiverequestdialog.ui b/src/qt/forms/receiverequestdialog.ui index 4f53dc19b8..fc0d10b4e4 100644 --- a/src/qt/forms/receiverequestdialog.ui +++ b/src/qt/forms/receiverequestdialog.ui @@ -17,7 +17,7 @@ - + 0 0 @@ -40,40 +40,9 @@ - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - &Save Image... - - - - - - - - - Bitcoin URI: - - - - - + - + 0 0 @@ -93,146 +62,46 @@ - - - Payment information: - - - - - - - - - - QFormLayout::AllNonFixedFieldsGrow - - - - - Label: - - - Qt::PlainText - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - lnLabel - - - - - - - true - - - true - - - - - - - Message: - - - Qt::PlainText - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - lnMessage - - - - - - - true - - - true - - - - - - - - 0 - 0 - - - - Amount: - - - Qt::PlainText - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - lnReqAmount - - - - - - - true - - - - 80 - 0 - - - - true - - - - - - - Address: - - - Qt::PlainText - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - reqAddress - - - - - - - true - - - - - - - + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Copy &URI + + + + + + + &Copy Image + + + + + + + &Save Image... + + + +
- - BitcoinAmountField - QWidget -
bitcoinamountfield.h
-
QRImageWidget QLabel diff --git a/src/qt/receivecoinsdialog.cpp b/src/qt/receivecoinsdialog.cpp index fff678d0c6..f3ab343fea 100644 --- a/src/qt/receivecoinsdialog.cpp +++ b/src/qt/receivecoinsdialog.cpp @@ -98,8 +98,9 @@ void ReceiveCoinsDialog::on_receiveButton_clicked() } SendCoinsRecipient info(address, label, ui->reqAmount->value(), ui->reqMessage->text()); - ReceiveRequestDialog *dialog = new ReceiveRequestDialog(info, this); + ReceiveRequestDialog *dialog = new ReceiveRequestDialog(this); dialog->setModel(model->getOptionsModel()); + dialog->setInfo(info); dialog->setAttribute(Qt::WA_DeleteOnClose); dialog->show(); clear(); diff --git a/src/qt/receiverequestdialog.cpp b/src/qt/receiverequestdialog.cpp index efbc6ebd70..f6031e2b47 100644 --- a/src/qt/receiverequestdialog.cpp +++ b/src/qt/receiverequestdialog.cpp @@ -9,6 +9,9 @@ #include #include +#include +#include +#include #if QT_VERSION < 0x050000 #include #endif @@ -64,34 +67,21 @@ void QRImageWidget::copyImage() QApplication::clipboard()->setImage(exportImage()); } -ReceiveRequestDialog::ReceiveRequestDialog(const SendCoinsRecipient &info, QWidget *parent) : +ReceiveRequestDialog::ReceiveRequestDialog(QWidget *parent) : QDialog(parent), ui(new Ui::ReceiveRequestDialog), - model(0), - info(info) + model(0) { ui->setupUi(this); - QString target = info.label; - if(target.isEmpty()) - target = info.address; - setWindowTitle(tr("Request payment to %1").arg(target)); - - ui->lnAddress->setText(info.address); - if(info.amount) - ui->lnReqAmount->setValue(info.amount); - ui->lnReqAmount->setReadOnly(true); - ui->lnLabel->setText(info.label); - ui->lnMessage->setText(info.message); - #ifndef USE_QRCODE ui->btnSaveAs->setVisible(false); + ui->btnCopyImage->setVisible(false); ui->lblQRCode->setVisible(false); #endif connect(ui->btnSaveAs, SIGNAL(clicked()), ui->lblQRCode, SLOT(saveImage())); - - genCode(); + connect(ui->btnCopyImage, SIGNAL(clicked()), ui->lblQRCode, SLOT(copyImage())); } ReceiveRequestDialog::~ReceiveRequestDialog() @@ -104,17 +94,42 @@ void ReceiveRequestDialog::setModel(OptionsModel *model) this->model = model; if (model) - connect(model, SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit())); + connect(model, SIGNAL(displayUnitChanged(int)), this, SLOT(update())); - // update the display unit, to not use the default ("BTC") - updateDisplayUnit(); + // update the display unit if necessary + update(); } -void ReceiveRequestDialog::genCode() +void ReceiveRequestDialog::setInfo(const SendCoinsRecipient &info) { + this->info = info; + update(); +} + +void ReceiveRequestDialog::update() +{ + if(!model) + return; + QString target = info.label; + if(target.isEmpty()) + target = info.address; + setWindowTitle(tr("Request payment to %1").arg(target)); + QString uri = GUIUtil::formatBitcoinURI(info); ui->btnSaveAs->setEnabled(false); - ui->outUri->setPlainText(uri); + QString html; + html += ""; + html += "" + GUIUtil::HtmlEscape(uri) + "
"; + html += "
"; + html += ""+tr("Payment information")+"
"; + html += ""+tr("Address")+": " + GUIUtil::HtmlEscape(info.address) + "
"; + if(info.amount) + html += ""+tr("Amount")+": " + BitcoinUnits::formatWithUnit(model->getDisplayUnit(), info.amount) + "
"; + if(!info.label.isEmpty()) + html += ""+tr("Label")+": " + GUIUtil::HtmlEscape(info.label) + "
"; + if(!info.message.isEmpty()) + html += ""+tr("Message")+": " + GUIUtil::HtmlEscape(info.message) + "
"; + ui->outUri->setText(html); #ifdef USE_QRCODE ui->lblQRCode->setText(""); @@ -151,26 +166,10 @@ void ReceiveRequestDialog::genCode() #endif } -void ReceiveRequestDialog::on_lnReqAmount_textChanged() +void ReceiveRequestDialog::on_btnCopyURI_clicked() { - genCode(); + QString uri = GUIUtil::formatBitcoinURI(info); + QApplication::clipboard()->setText(uri, QClipboard::Clipboard); + QApplication::clipboard()->setText(uri, QClipboard::Selection); } -void ReceiveRequestDialog::on_lnLabel_textChanged() -{ - genCode(); -} - -void ReceiveRequestDialog::on_lnMessage_textChanged() -{ - genCode(); -} - -void ReceiveRequestDialog::updateDisplayUnit() -{ - if (model) - { - // Update lnReqAmount with the current unit - ui->lnReqAmount->setDisplayUnit(model->getDisplayUnit()); - } -} diff --git a/src/qt/receiverequestdialog.h b/src/qt/receiverequestdialog.h index bfe50bde77..8db1ad83a1 100644 --- a/src/qt/receiverequestdialog.h +++ b/src/qt/receiverequestdialog.h @@ -36,25 +36,21 @@ class ReceiveRequestDialog : public QDialog Q_OBJECT public: - explicit ReceiveRequestDialog(const SendCoinsRecipient &info, QWidget *parent = 0); + explicit ReceiveRequestDialog(QWidget *parent = 0); ~ReceiveRequestDialog(); void setModel(OptionsModel *model); + void setInfo(const SendCoinsRecipient &info); private slots: - void on_lnReqAmount_textChanged(); - void on_lnLabel_textChanged(); - void on_lnMessage_textChanged(); + void on_btnCopyURI_clicked(); - void updateDisplayUnit(); + void update(); private: Ui::ReceiveRequestDialog *ui; OptionsModel *model; SendCoinsRecipient info; - - void genCode(); - QString getURI(); }; #endif // QRCODEDIALOG_H From 70b14636cd60529c87b2cc61516f5d1bf49299a5 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 18 Oct 2013 19:42:40 +0200 Subject: [PATCH 8/8] qt: general polish after adding new receive flow - We no longer have an address book, but "address lists", update message accordingly - Add tooltips here and there - Clarify text on buttons - add Copy Address button to receive request dialog --- src/qt/addressbookpage.cpp | 6 +- src/qt/forms/addressbookpage.ui | 18 ++---- src/qt/forms/editaddressdialog.ui | 4 +- src/qt/forms/receivecoinsdialog.ui | 22 +++++-- src/qt/forms/receiverequestdialog.ui | 84 ++++++++++++++++++++----- src/qt/forms/sendcoinsentry.ui | 5 +- src/qt/forms/signverifymessagedialog.ui | 6 +- src/qt/receiverequestdialog.cpp | 12 +++- src/qt/receiverequestdialog.h | 1 + 9 files changed, 115 insertions(+), 43 deletions(-) diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp index 7fbdf2e9c5..0b364afca8 100644 --- a/src/qt/addressbookpage.cpp +++ b/src/qt/addressbookpage.cpp @@ -45,6 +45,7 @@ AddressBookPage::AddressBookPage(Mode mode, Tabs tab, QWidget *parent) : connect(ui->tableView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(accept())); ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers); ui->tableView->setFocus(); + ui->closeButton->setText(tr("C&hoose")); ui->exportButton->hide(); break; case ForEditing: @@ -90,8 +91,7 @@ AddressBookPage::AddressBookPage(Mode mode, Tabs tab, QWidget *parent) : connect(ui->tableView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextualMenu(QPoint))); - // Pass through accept action from button box - connect(ui->buttonBox, SIGNAL(accepted()), this, SLOT(accept())); + connect(ui->closeButton, SIGNAL(clicked()), this, SLOT(accept())); } AddressBookPage::~AddressBookPage() @@ -268,7 +268,7 @@ void AddressBookPage::on_exportButton_clicked() // CSV is currently the only supported format QString filename = GUIUtil::getSaveFileName( this, - tr("Export Address Book Data"), QString(), + tr("Export Address List"), QString(), tr("Comma separated file (*.csv)")); if (filename.isNull()) return; diff --git a/src/qt/forms/addressbookpage.ui b/src/qt/forms/addressbookpage.ui index 9edaf74023..5a92a455b1 100644 --- a/src/qt/forms/addressbookpage.ui +++ b/src/qt/forms/addressbookpage.ui @@ -11,7 +11,7 @@ - + @@ -60,7 +60,7 @@ Create a new address - &New Address + &New @@ -74,7 +74,7 @@ Copy the currently selected address to the system clipboard - &Copy Address + &Copy @@ -124,15 +124,9 @@
- - - - 0 - 0 - - - - QDialogButtonBox::Ok + + + C&lose diff --git a/src/qt/forms/editaddressdialog.ui b/src/qt/forms/editaddressdialog.ui index b4a4c1b1e9..8ff3805226 100644 --- a/src/qt/forms/editaddressdialog.ui +++ b/src/qt/forms/editaddressdialog.ui @@ -32,7 +32,7 @@ - The label associated with this address book entry + The label associated with this address list entry @@ -49,7 +49,7 @@ - The address associated with this address book entry. This can only be modified for sending addresses. + The address associated with this address list entry. This can only be modified for sending addresses. diff --git a/src/qt/forms/receivecoinsdialog.ui b/src/qt/forms/receivecoinsdialog.ui index a5946883bd..e01a23b9c4 100644 --- a/src/qt/forms/receivecoinsdialog.ui +++ b/src/qt/forms/receivecoinsdialog.ui @@ -30,13 +30,16 @@ - + 80 0 + + The amount to request + @@ -50,7 +53,11 @@ - + + + The label to associate with the receiving address + + @@ -63,7 +70,11 @@ - + + + The message to attach to payment request + + @@ -74,8 +85,11 @@ + + Reuse one of the previously used receiving addresses. Reusing addresses has security and privacy issues. Do not use this unless re-generating a payment request made before. + - R&euse an existing receiving address + R&euse an existing receiving address (not recommended) diff --git a/src/qt/forms/receiverequestdialog.ui b/src/qt/forms/receiverequestdialog.ui index fc0d10b4e4..d7724ef915 100644 --- a/src/qt/forms/receiverequestdialog.ui +++ b/src/qt/forms/receiverequestdialog.ui @@ -28,6 +28,9 @@ 300 + + QR Code + Qt::PlainText @@ -53,6 +56,12 @@ 50 + + QFrame::NoFrame + + + QFrame::Plain + true @@ -63,19 +72,6 @@ - - - - Qt::Horizontal - - - - 40 - 20 - - - - @@ -83,6 +79,13 @@ + + + + Copy &Address + + + @@ -97,6 +100,26 @@ + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + QDialogButtonBox::Close + + +
@@ -109,5 +132,38 @@ - + + + buttonBox + rejected() + ReceiveRequestDialog + reject() + + + 452 + 573 + + + 243 + 298 + + + + + buttonBox + accepted() + ReceiveRequestDialog + accept() + + + 452 + 573 + + + 243 + 298 + + + + diff --git a/src/qt/forms/sendcoinsentry.ui b/src/qt/forms/sendcoinsentry.ui index 5c6afd6c71..db742d633d 100644 --- a/src/qt/forms/sendcoinsentry.ui +++ b/src/qt/forms/sendcoinsentry.ui @@ -87,7 +87,7 @@ - Choose address from address book + Choose previously used address @@ -137,7 +137,7 @@ - Enter a label for this address to add it to your address book + Enter a label for this address to add it to the list of used addresses @@ -674,7 +674,6 @@ BitcoinAmountField QLineEdit
bitcoinamountfield.h
- 1 QValidatedLineEdit diff --git a/src/qt/forms/signverifymessagedialog.ui b/src/qt/forms/signverifymessagedialog.ui index 279b2a5052..16cc6c2ea1 100644 --- a/src/qt/forms/signverifymessagedialog.ui +++ b/src/qt/forms/signverifymessagedialog.ui @@ -20,7 +20,7 @@ - 0 + 1 @@ -58,7 +58,7 @@ - Choose an address from the address book + Choose previously used address @@ -271,7 +271,7 @@ - Choose an address from the address book + Choose previously used address diff --git a/src/qt/receiverequestdialog.cpp b/src/qt/receiverequestdialog.cpp index f6031e2b47..cb0a07fcdf 100644 --- a/src/qt/receiverequestdialog.cpp +++ b/src/qt/receiverequestdialog.cpp @@ -44,12 +44,15 @@ void QRImageWidget::mousePressEvent(QMouseEvent *event) { if(event->button() == Qt::LeftButton) { + event->accept(); QMimeData *mimeData = new QMimeData; mimeData->setImageData(exportImage()); QDrag *drag = new QDrag(this); drag->setMimeData(mimeData); drag->exec(); + } else { + QLabel::mousePressEvent(event); } } @@ -119,9 +122,9 @@ void ReceiveRequestDialog::update() ui->btnSaveAs->setEnabled(false); QString html; html += ""; - html += "" + GUIUtil::HtmlEscape(uri) + "
"; - html += "
"; html += ""+tr("Payment information")+"
"; + html += ""+tr("URI")+": "; + html += "" + GUIUtil::HtmlEscape(uri) + "
"; html += ""+tr("Address")+": " + GUIUtil::HtmlEscape(info.address) + "
"; if(info.amount) html += ""+tr("Amount")+": " + BitcoinUnits::formatWithUnit(model->getDisplayUnit(), info.amount) + "
"; @@ -173,3 +176,8 @@ void ReceiveRequestDialog::on_btnCopyURI_clicked() QApplication::clipboard()->setText(uri, QClipboard::Selection); } +void ReceiveRequestDialog::on_btnCopyAddress_clicked() +{ + QApplication::clipboard()->setText(info.address, QClipboard::Clipboard); + QApplication::clipboard()->setText(info.address, QClipboard::Selection); +} diff --git a/src/qt/receiverequestdialog.h b/src/qt/receiverequestdialog.h index 8db1ad83a1..1beb873dfd 100644 --- a/src/qt/receiverequestdialog.h +++ b/src/qt/receiverequestdialog.h @@ -44,6 +44,7 @@ public: private slots: void on_btnCopyURI_clicked(); + void on_btnCopyAddress_clicked(); void update();