From 0ba948aa4f91b8a03a34eb2b9cf372e89f21d5df Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Thu, 29 Aug 2019 00:39:48 +0000 Subject: [PATCH] GUI: SendConfirmationDialog: Enable changing the actual buttons used Both buttons can be replaced with other standard buttons --- src/qt/sendcoinsdialog.cpp | 40 ++++++++++++++++++++++++++++++++----- src/qt/sendcoinsdialog.h | 4 ++++ src/qt/test/wallettests.cpp | 15 ++++++++++++++ src/qt/walletmodel.cpp | 2 +- 4 files changed, 55 insertions(+), 6 deletions(-) diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 2ef503b8e4..37dc310e7b 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -486,7 +486,7 @@ void SendCoinsDialog::sendButtonClicked([[maybe_unused]] bool checked) const bool enable_send{!model->wallet().privateKeysDisabled() || model->wallet().hasExternalSigner()}; const bool always_show_unsigned{model->getOptionsModel()->getEnablePSBTControls()}; auto confirmationDialog = new SendConfirmationDialog(confirmation, question_string, informative_text, detailed_text, SEND_CONFIRM_DELAY, enable_send, always_show_unsigned, this); - confirmationDialog->setAttribute(Qt::WA_DeleteOnClose); + confirmationDialog->m_delete_on_close = true; // TODO: Replace QDialog::exec() with safer QDialog::show(). const auto retval = static_cast(confirmationDialog->exec()); @@ -1066,10 +1066,26 @@ SendConfirmationDialog::SendConfirmationDialog(const QString& title, const QStri int SendConfirmationDialog::exec() { - setStandardButtons(QMessageBox::Yes | QMessageBox::Cancel); + setStandardButtons(m_yes_button | m_cancel_button); + + yesButton = button(m_yes_button); + QAbstractButton * const cancel_button_obj = button(m_cancel_button); + + if (m_yes_button != QMessageBox::Yes || m_cancel_button != QMessageBox::Cancel) { + // We need to ensure the buttons have Yes/No roles, or they'll get ordered weird + // But only do it for customised yes/cancel buttons, so simple code can check results simply too + removeButton(cancel_button_obj); + addButton(cancel_button_obj, QMessageBox::NoRole); + setEscapeButton(cancel_button_obj); + + removeButton(yesButton); + addButton(yesButton, QMessageBox::YesRole); + } + if (m_enable_save) addButton(QMessageBox::Save); - setDefaultButton(QMessageBox::Cancel); - yesButton = button(QMessageBox::Yes); + + setDefaultButton(m_cancel_button); + if (confirmButtonText.isEmpty()) { confirmButtonText = yesButton->text(); } @@ -1079,7 +1095,21 @@ int SendConfirmationDialog::exec() connect(&countDownTimer, &QTimer::timeout, this, &SendConfirmationDialog::countDown); countDownTimer.start(1s); - return QMessageBox::exec(); + QMessageBox::exec(); + + int rv; + const auto clicked_button = clickedButton(); + if (clicked_button == m_psbt_button) { + rv = QMessageBox::Save; + } else if (clicked_button == yesButton) { + rv = QMessageBox::Yes; + } else { + rv = QMessageBox::Cancel; + } + + if (m_delete_on_close) delete this; + + return rv; } void SendConfirmationDialog::countDown() diff --git a/src/qt/sendcoinsdialog.h b/src/qt/sendcoinsdialog.h index 85229514ff..c1aa9f98ff 100644 --- a/src/qt/sendcoinsdialog.h +++ b/src/qt/sendcoinsdialog.h @@ -129,6 +129,10 @@ class SendConfirmationDialog : public QMessageBox Q_OBJECT public: + bool m_delete_on_close{false}; + QMessageBox::StandardButton m_yes_button{QMessageBox::Yes}; + QMessageBox::StandardButton m_cancel_button{QMessageBox::Cancel}; + SendConfirmationDialog(const QString& title, const QString& text, const QString& informative_text = "", const QString& detailed_text = "", int secDelay = SEND_CONFIRM_DELAY, bool enable_send = true, bool always_show_unsigned = true, QWidget* parent = nullptr); /* Returns QMessageBox::Cancel, QMessageBox::Yes when "Send" is clicked and QMessageBox::Save when "Create Unsigned" is clicked. */ diff --git a/src/qt/test/wallettests.cpp b/src/qt/test/wallettests.cpp index 603df0b15f..936a6d2742 100644 --- a/src/qt/test/wallettests.cpp +++ b/src/qt/test/wallettests.cpp @@ -67,6 +67,21 @@ void ConfirmSend(QString* text = nullptr, QMessageBox::StandardButton confirm_ty SendConfirmationDialog* dialog = qobject_cast(widget); if (text) *text = dialog->text(); QAbstractButton* button = dialog->button(confirm_type); + if (!button) { + const QMessageBox::ButtonRole confirm_role = [confirm_type](){ + switch (confirm_type) { + case QMessageBox::Yes: return QMessageBox::YesRole; + case QMessageBox::Cancel: return QMessageBox::NoRole; + default: assert(0); + } + }(); + for (QAbstractButton* maybe_button : dialog->buttons()) { + if (dialog->buttonRole(maybe_button) == confirm_role) { + button = maybe_button; + break; + } + } + } button->setEnabled(true); button->click(); } diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index 1bdf94d3b5..270e9aea45 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -520,7 +520,7 @@ bool WalletModel::bumpFee(uint256 hash, uint256& new_hash) const bool enable_send{!wallet().privateKeysDisabled() || wallet().hasExternalSigner()}; const bool always_show_unsigned{getOptionsModel()->getEnablePSBTControls()}; auto confirmationDialog = new SendConfirmationDialog(tr("Confirm fee bump"), questionString, "", "", SEND_CONFIRM_DELAY, enable_send, always_show_unsigned, nullptr); - confirmationDialog->setAttribute(Qt::WA_DeleteOnClose); + confirmationDialog->m_delete_on_close = true; // TODO: Replace QDialog::exec() with safer QDialog::show(). const auto retval = static_cast(confirmationDialog->exec());