diff --git a/src/qt/forms/receivecoinsdialog.ui b/src/qt/forms/receivecoinsdialog.ui index 85df65f..ccd8ac7 100644 --- a/src/qt/forms/receivecoinsdialog.ui +++ b/src/qt/forms/receivecoinsdialog.ui @@ -189,28 +189,40 @@ - - - - 0 - 0 - - - - - 1000 - 16777215 - - - - Qt::StrongFocus - - - Native segwit addresses (aka Bech32 or BIP-173) reduce your transaction fees later on and offer better protection against typos, but old wallets don't support them. When unchecked, an address compatible with older wallets will be created instead. - + - Generate native segwit (Bech32) address + Address type: + + addressType + + + + + + + Select the address type to generate for this payment request. + + + + legacy + + + + + p2sh-segwit + + + + + segwit + + + + + taproot + + @@ -360,7 +372,7 @@ reqLabel reqAmount - useBech32 + addressType reqMessage receiveButton clearButton diff --git a/src/qt/receivecoinsdialog.cpp b/src/qt/receivecoinsdialog.cpp index 9607ff0..ce9f098 100644 --- a/src/qt/receivecoinsdialog.cpp +++ b/src/qt/receivecoinsdialog.cpp @@ -4,8 +4,8 @@ #include -#include #include +#include #include #include @@ -14,20 +14,69 @@ #include #include +#include + #include +#include #include #include #include #include -ReceiveCoinsDialog::ReceiveCoinsDialog(const PlatformStyle *_platformStyle, QWidget *parent) : - QDialog(parent), - ui(new Ui::ReceiveCoinsDialog), - columnResizingFixer(nullptr), - model(nullptr), - platformStyle(_platformStyle) +#include + +namespace { +const std::array RECEIVE_ADDRESS_TYPES = { + OutputType::LEGACY, + OutputType::P2SH_SEGWIT, + OutputType::BECH32, + OutputType::BECH32M, +}; + +QString AddressTypeDisplayName(OutputType type) +{ + switch (type) { + case OutputType::LEGACY: return QStringLiteral("legacy"); + case OutputType::P2SH_SEGWIT: return QStringLiteral("p2sh-segwit"); + case OutputType::BECH32: return QStringLiteral("segwit"); + case OutputType::BECH32M: return QStringLiteral("traproot"); + default: return QStringLiteral("legacy"); + } +} + +void InitAddressTypeComboBox(QComboBox* combo) +{ + combo->clear(); + for (const auto type : RECEIVE_ADDRESS_TYPES) { + combo->addItem(AddressTypeDisplayName(type), static_cast(type)); + } +} + +void SetAddressType(QComboBox* combo, OutputType type, OutputType fallback = OutputType::BECH32) +{ + int idx = combo->findData(static_cast(type)); + if (idx < 0) idx = combo->findData(static_cast(fallback)); + if (idx < 0) idx = 0; + combo->setCurrentIndex(idx); +} + +OutputType GetSelectedAddressType(const QComboBox* combo, OutputType fallback) +{ + const QVariant type_data = combo->currentData(); + if (!type_data.isValid()) return fallback; + return static_cast(type_data.toInt()); +} +} // namespace + +ReceiveCoinsDialog::ReceiveCoinsDialog(const PlatformStyle* _platformStyle, QWidget* parent) : QDialog(parent), + ui(new Ui::ReceiveCoinsDialog), + columnResizingFixer(nullptr), + model(nullptr), + platformStyle(_platformStyle) { ui->setupUi(this); + InitAddressTypeComboBox(ui->addressType); + SetAddressType(ui->addressType, OutputType::BECH32); if (!_platformStyle->getImagesOnButtons()) { ui->clearButton->setIcon(QIcon()); @@ -42,10 +91,10 @@ ReceiveCoinsDialog::ReceiveCoinsDialog(const PlatformStyle *_platformStyle, QWid } // context menu actions - QAction *copyURIAction = new QAction(tr("Copy URI"), this); - QAction *copyLabelAction = new QAction(tr("Copy label"), this); - QAction *copyMessageAction = new QAction(tr("Copy message"), this); - QAction *copyAmountAction = new QAction(tr("Copy amount"), this); + QAction* copyURIAction = new QAction(tr("Copy URI"), this); + QAction* copyLabelAction = new QAction(tr("Copy label"), this); + QAction* copyMessageAction = new QAction(tr("Copy message"), this); + QAction* copyAmountAction = new QAction(tr("Copy amount"), this); // context menu contextMenu = new QMenu(this); @@ -64,12 +113,11 @@ ReceiveCoinsDialog::ReceiveCoinsDialog(const PlatformStyle *_platformStyle, QWid connect(ui->clearButton, &QPushButton::clicked, this, &ReceiveCoinsDialog::clear); } -void ReceiveCoinsDialog::setModel(WalletModel *_model) +void ReceiveCoinsDialog::setModel(WalletModel* _model) { this->model = _model; - if(_model && _model->getOptionsModel()) - { + if (_model && _model->getOptionsModel()) { _model->getRecentRequestsTableModel()->sort(RecentRequestsTableModel::Date, Qt::DescendingOrder); connect(_model->getOptionsModel(), &OptionsModel::displayUnitChanged, this, &ReceiveCoinsDialog::updateDisplayUnit); updateDisplayUnit(); @@ -92,11 +140,7 @@ void ReceiveCoinsDialog::setModel(WalletModel *_model) // Last 2 columns are set by the columnResizingFixer, when the table geometry is ready. columnResizingFixer = new GUIUtil::TableViewLastColumnResizingFixer(tableView, AMOUNT_MINIMUM_COLUMN_WIDTH, DATE_COLUMN_WIDTH, this); - if (model->wallet().getDefaultAddressType() == OutputType::BECH32) { - ui->useBech32->setCheckState(Qt::Checked); - } else { - ui->useBech32->setCheckState(Qt::Unchecked); - } + SetAddressType(ui->addressType, model->wallet().getDefaultAddressType()); // Set the button to be enabled or disabled based on whether the wallet can give out new addresses. ui->receiveButton->setEnabled(model->wallet().canGetAddresses()); @@ -133,33 +177,24 @@ void ReceiveCoinsDialog::accept() void ReceiveCoinsDialog::updateDisplayUnit() { - if(model && model->getOptionsModel()) - { + if (model && model->getOptionsModel()) { ui->reqAmount->setDisplayUnit(model->getOptionsModel()->getDisplayUnit()); } } void ReceiveCoinsDialog::on_receiveButton_clicked() { - if(!model || !model->getOptionsModel() || !model->getAddressTableModel() || !model->getRecentRequestsTableModel()) + if (!model || !model->getOptionsModel() || !model->getAddressTableModel() || !model->getRecentRequestsTableModel()) return; QString address; QString label = ui->reqLabel->text(); /* Generate new receiving address */ - OutputType address_type; - if (ui->useBech32->isChecked()) { - address_type = OutputType::BECH32; - } else { - address_type = model->wallet().getDefaultAddressType(); - if (address_type == OutputType::BECH32) { - address_type = OutputType::P2SH_SEGWIT; - } - } + const OutputType address_type = GetSelectedAddressType(ui->addressType, model->wallet().getDefaultAddressType()); address = model->getAddressTableModel()->addRow(AddressTableModel::Receive, label, "", address_type); SendCoinsRecipient info(address, label, ui->reqAmount->value(), ui->reqMessage->text()); - ReceiveRequestDialog *dialog = new ReceiveRequestDialog(this); + ReceiveRequestDialog* dialog = new ReceiveRequestDialog(this); dialog->setAttribute(Qt::WA_DeleteOnClose); dialog->setModel(model); dialog->setInfo(info); @@ -170,17 +205,17 @@ void ReceiveCoinsDialog::on_receiveButton_clicked() model->getRecentRequestsTableModel()->addNewRequest(info); } -void ReceiveCoinsDialog::on_recentRequestsView_doubleClicked(const QModelIndex &index) +void ReceiveCoinsDialog::on_recentRequestsView_doubleClicked(const QModelIndex& index) { - const RecentRequestsTableModel *submodel = model->getRecentRequestsTableModel(); - ReceiveRequestDialog *dialog = new ReceiveRequestDialog(this); + const RecentRequestsTableModel* submodel = model->getRecentRequestsTableModel(); + ReceiveRequestDialog* dialog = new ReceiveRequestDialog(this); dialog->setModel(model); dialog->setInfo(submodel->entry(index.row()).recipient); dialog->setAttribute(Qt::WA_DeleteOnClose); dialog->show(); } -void ReceiveCoinsDialog::recentRequestsView_selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) +void ReceiveCoinsDialog::recentRequestsView_selectionChanged(const QItemSelection& selected, const QItemSelection& deselected) { // Enable Show/Remove buttons only if anything is selected. bool enable = !ui->recentRequestsView->selectionModel()->selectedRows().isEmpty(); @@ -190,7 +225,7 @@ void ReceiveCoinsDialog::recentRequestsView_selectionChanged(const QItemSelectio void ReceiveCoinsDialog::on_showRequestButton_clicked() { - if(!model || !model->getRecentRequestsTableModel() || !ui->recentRequestsView->selectionModel()) + if (!model || !model->getRecentRequestsTableModel() || !ui->recentRequestsView->selectionModel()) return; QModelIndexList selection = ui->recentRequestsView->selectionModel()->selectedRows(); @@ -201,10 +236,10 @@ void ReceiveCoinsDialog::on_showRequestButton_clicked() void ReceiveCoinsDialog::on_removeRequestButton_clicked() { - if(!model || !model->getRecentRequestsTableModel() || !ui->recentRequestsView->selectionModel()) + if (!model || !model->getRecentRequestsTableModel() || !ui->recentRequestsView->selectionModel()) return; QModelIndexList selection = ui->recentRequestsView->selectionModel()->selectedRows(); - if(selection.empty()) + if (selection.empty()) return; // correct for selection mode ContiguousSelection QModelIndex firstIndex = selection.at(0); @@ -213,19 +248,17 @@ void ReceiveCoinsDialog::on_removeRequestButton_clicked() // We override the virtual resizeEvent of the QWidget to adjust tables column // sizes as the tables width is proportional to the dialogs width. -void ReceiveCoinsDialog::resizeEvent(QResizeEvent *event) +void ReceiveCoinsDialog::resizeEvent(QResizeEvent* event) { QWidget::resizeEvent(event); columnResizingFixer->stretchColumnWidth(RecentRequestsTableModel::Message); } -void ReceiveCoinsDialog::keyPressEvent(QKeyEvent *event) +void ReceiveCoinsDialog::keyPressEvent(QKeyEvent* event) { - if (event->key() == Qt::Key_Return) - { + if (event->key() == Qt::Key_Return) { // press return -> submit form - if (ui->reqLabel->hasFocus() || ui->reqAmount->hasFocus() || ui->reqMessage->hasFocus()) - { + if (ui->reqLabel->hasFocus() || ui->reqAmount->hasFocus() || ui->reqMessage->hasFocus()) { event->ignore(); on_receiveButton_clicked(); return; @@ -237,10 +270,10 @@ void ReceiveCoinsDialog::keyPressEvent(QKeyEvent *event) QModelIndex ReceiveCoinsDialog::selectedRow() { - if(!model || !model->getRecentRequestsTableModel() || !ui->recentRequestsView->selectionModel()) + if (!model || !model->getRecentRequestsTableModel() || !ui->recentRequestsView->selectionModel()) return QModelIndex(); QModelIndexList selection = ui->recentRequestsView->selectionModel()->selectedRows(); - if(selection.empty()) + if (selection.empty()) return QModelIndex(); // correct for selection mode ContiguousSelection QModelIndex firstIndex = selection.at(0); @@ -258,7 +291,7 @@ void ReceiveCoinsDialog::copyColumnToClipboard(int column) } // context menu -void ReceiveCoinsDialog::showMenu(const QPoint &point) +void ReceiveCoinsDialog::showMenu(const QPoint& point) { if (!selectedRow().isValid()) { return; @@ -274,7 +307,7 @@ void ReceiveCoinsDialog::copyURI() return; } - const RecentRequestsTableModel * const submodel = model->getRecentRequestsTableModel(); + const RecentRequestsTableModel* const submodel = model->getRecentRequestsTableModel(); const QString uri = GUIUtil::formatPalladiumURI(submodel->entry(sel.row()).recipient); GUIUtil::setClipboard(uri); }