[gui] send dialog: split on_sendButton_clicked

This commit does not change behavior.
This commit is contained in:
Sjors Provoost
2019-11-18 15:54:39 +01:00
parent 5236b2e267
commit 6ab3aad9a5
2 changed files with 52 additions and 44 deletions

View File

@@ -219,11 +219,8 @@ SendCoinsDialog::~SendCoinsDialog()
delete ui; delete ui;
} }
void SendCoinsDialog::on_sendButton_clicked() bool SendCoinsDialog::PrepareSendText(QString& question_string, QString& informative_text, QString& detailed_text)
{ {
if(!model || !model->getOptionsModel())
return;
QList<SendCoinsRecipient> recipients; QList<SendCoinsRecipient> recipients;
bool valid = true; bool valid = true;
@@ -246,7 +243,7 @@ void SendCoinsDialog::on_sendButton_clicked()
if(!valid || recipients.isEmpty()) if(!valid || recipients.isEmpty())
{ {
return; return false;
} }
fNewRecipientAllowed = false; fNewRecipientAllowed = false;
@@ -255,11 +252,11 @@ void SendCoinsDialog::on_sendButton_clicked()
{ {
// Unlock wallet was cancelled // Unlock wallet was cancelled
fNewRecipientAllowed = true; fNewRecipientAllowed = true;
return; return false;
} }
// prepare transaction for getting txFee earlier // prepare transaction for getting txFee earlier
WalletModelTransaction currentTransaction(recipients); m_current_transaction = MakeUnique<WalletModelTransaction>(recipients);
WalletModel::SendCoinsReturn prepareStatus; WalletModel::SendCoinsReturn prepareStatus;
// Always use a CCoinControl instance, use the CoinControlDialog instance if CoinControl has been enabled // Always use a CCoinControl instance, use the CoinControlDialog instance if CoinControl has been enabled
@@ -269,22 +266,20 @@ void SendCoinsDialog::on_sendButton_clicked()
updateCoinControlState(ctrl); updateCoinControlState(ctrl);
prepareStatus = model->prepareTransaction(currentTransaction, ctrl); prepareStatus = model->prepareTransaction(*m_current_transaction, ctrl);
// process prepareStatus and on error generate message shown to user // process prepareStatus and on error generate message shown to user
processSendCoinsReturn(prepareStatus, processSendCoinsReturn(prepareStatus,
BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), currentTransaction.getTransactionFee())); BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), m_current_transaction->getTransactionFee()));
if(prepareStatus.status != WalletModel::OK) { if(prepareStatus.status != WalletModel::OK) {
fNewRecipientAllowed = true; fNewRecipientAllowed = true;
return; return false;
} }
CAmount txFee = currentTransaction.getTransactionFee(); CAmount txFee = m_current_transaction->getTransactionFee();
// Format confirmation message
QStringList formatted; QStringList formatted;
for (const SendCoinsRecipient &rcp : currentTransaction.getRecipients()) for (const SendCoinsRecipient &rcp : m_current_transaction->getRecipients())
{ {
// generate amount string with wallet name in case of multiwallet // generate amount string with wallet name in case of multiwallet
QString amount = BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), rcp.amount); QString amount = BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), rcp.amount);
@@ -311,72 +306,82 @@ void SendCoinsDialog::on_sendButton_clicked()
formatted.append(recipientElement); formatted.append(recipientElement);
} }
QString questionString;
if (model->wallet().privateKeysDisabled()) { if (model->wallet().privateKeysDisabled()) {
questionString.append(tr("Do you want to draft this transaction?")); question_string.append(tr("Do you want to draft this transaction?"));
} else { } else {
questionString.append(tr("Are you sure you want to send?")); question_string.append(tr("Are you sure you want to send?"));
} }
questionString.append("<br /><span style='font-size:10pt;'>"); question_string.append("<br /><span style='font-size:10pt;'>");
if (model->wallet().privateKeysDisabled()) { if (model->wallet().privateKeysDisabled()) {
questionString.append(tr("Please, review your transaction proposal. This will produce a Partially Signed Bitcoin Transaction (PSBT) which you can copy and then sign with e.g. an offline %1 wallet, or a PSBT-compatible hardware wallet.").arg(PACKAGE_NAME)); question_string.append(tr("Please, review your transaction proposal. This will produce a Partially Signed Bitcoin Transaction (PSBT) which you can copy and then sign with e.g. an offline %1 wallet, or a PSBT-compatible hardware wallet.").arg(PACKAGE_NAME));
} else { } else {
questionString.append(tr("Please, review your transaction.")); question_string.append(tr("Please, review your transaction."));
} }
questionString.append("</span>%1"); question_string.append("</span>%1");
if(txFee > 0) if(txFee > 0)
{ {
// append fee string if a fee is required // append fee string if a fee is required
questionString.append("<hr /><b>"); question_string.append("<hr /><b>");
questionString.append(tr("Transaction fee")); question_string.append(tr("Transaction fee"));
questionString.append("</b>"); question_string.append("</b>");
// append transaction size // append transaction size
questionString.append(" (" + QString::number((double)currentTransaction.getTransactionSize() / 1000) + " kB): "); question_string.append(" (" + QString::number((double)m_current_transaction->getTransactionSize() / 1000) + " kB): ");
// append transaction fee value // append transaction fee value
questionString.append("<span style='color:#aa0000; font-weight:bold;'>"); question_string.append("<span style='color:#aa0000; font-weight:bold;'>");
questionString.append(BitcoinUnits::formatHtmlWithUnit(model->getOptionsModel()->getDisplayUnit(), txFee)); question_string.append(BitcoinUnits::formatHtmlWithUnit(model->getOptionsModel()->getDisplayUnit(), txFee));
questionString.append("</span><br />"); question_string.append("</span><br />");
// append RBF message according to transaction's signalling // append RBF message according to transaction's signalling
questionString.append("<span style='font-size:10pt; font-weight:normal;'>"); question_string.append("<span style='font-size:10pt; font-weight:normal;'>");
if (ui->optInRBF->isChecked()) { if (ui->optInRBF->isChecked()) {
questionString.append(tr("You can increase the fee later (signals Replace-By-Fee, BIP-125).")); question_string.append(tr("You can increase the fee later (signals Replace-By-Fee, BIP-125)."));
} else { } else {
questionString.append(tr("Not signalling Replace-By-Fee, BIP-125.")); question_string.append(tr("Not signalling Replace-By-Fee, BIP-125."));
} }
questionString.append("</span>"); question_string.append("</span>");
} }
// add total amount in all subdivision units // add total amount in all subdivision units
questionString.append("<hr />"); question_string.append("<hr />");
CAmount totalAmount = currentTransaction.getTotalTransactionAmount() + txFee; CAmount totalAmount = m_current_transaction->getTotalTransactionAmount() + txFee;
QStringList alternativeUnits; QStringList alternativeUnits;
for (const BitcoinUnits::Unit u : BitcoinUnits::availableUnits()) for (const BitcoinUnits::Unit u : BitcoinUnits::availableUnits())
{ {
if(u != model->getOptionsModel()->getDisplayUnit()) if(u != model->getOptionsModel()->getDisplayUnit())
alternativeUnits.append(BitcoinUnits::formatHtmlWithUnit(u, totalAmount)); alternativeUnits.append(BitcoinUnits::formatHtmlWithUnit(u, totalAmount));
} }
questionString.append(QString("<b>%1</b>: <b>%2</b>").arg(tr("Total Amount")) question_string.append(QString("<b>%1</b>: <b>%2</b>").arg(tr("Total Amount"))
.arg(BitcoinUnits::formatHtmlWithUnit(model->getOptionsModel()->getDisplayUnit(), totalAmount))); .arg(BitcoinUnits::formatHtmlWithUnit(model->getOptionsModel()->getDisplayUnit(), totalAmount)));
questionString.append(QString("<br /><span style='font-size:10pt; font-weight:normal;'>(=%1)</span>") question_string.append(QString("<br /><span style='font-size:10pt; font-weight:normal;'>(=%1)</span>")
.arg(alternativeUnits.join(" " + tr("or") + " "))); .arg(alternativeUnits.join(" " + tr("or") + " ")));
QString informative_text;
QString detailed_text;
if (formatted.size() > 1) { if (formatted.size() > 1) {
questionString = questionString.arg(""); question_string = question_string.arg("");
informative_text = tr("To review recipient list click \"Show Details...\""); informative_text = tr("To review recipient list click \"Show Details...\"");
detailed_text = formatted.join("\n\n"); detailed_text = formatted.join("\n\n");
} else { } else {
questionString = questionString.arg("<br /><br />" + formatted.at(0)); question_string = question_string.arg("<br /><br />" + formatted.at(0));
} }
return true;
}
void SendCoinsDialog::on_sendButton_clicked()
{
if(!model || !model->getOptionsModel())
return;
QString question_string, informative_text, detailed_text;
if (!PrepareSendText(question_string, informative_text, detailed_text)) return;
assert(m_current_transaction);
const QString confirmation = model->wallet().privateKeysDisabled() ? tr("Confirm transaction proposal") : tr("Confirm send coins"); const QString confirmation = model->wallet().privateKeysDisabled() ? tr("Confirm transaction proposal") : tr("Confirm send coins");
const QString confirmButtonText = model->wallet().privateKeysDisabled() ? tr("Copy PSBT to clipboard") : tr("Send"); const QString confirmButtonText = model->wallet().privateKeysDisabled() ? tr("Copy PSBT to clipboard") : tr("Send");
SendConfirmationDialog confirmationDialog(confirmation, questionString, informative_text, detailed_text, SEND_CONFIRM_DELAY, confirmButtonText, this); SendConfirmationDialog confirmationDialog(confirmation, question_string, informative_text, detailed_text, SEND_CONFIRM_DELAY, confirmButtonText, this);
confirmationDialog.exec(); confirmationDialog.exec();
QMessageBox::StandardButton retval = static_cast<QMessageBox::StandardButton>(confirmationDialog.result()); QMessageBox::StandardButton retval = static_cast<QMessageBox::StandardButton>(confirmationDialog.result());
@@ -388,7 +393,7 @@ void SendCoinsDialog::on_sendButton_clicked()
bool send_failure = false; bool send_failure = false;
if (model->wallet().privateKeysDisabled()) { if (model->wallet().privateKeysDisabled()) {
CMutableTransaction mtx = CMutableTransaction{*(currentTransaction.getWtx())}; CMutableTransaction mtx = CMutableTransaction{*(m_current_transaction->getWtx())};
PartiallySignedTransaction psbtx(mtx); PartiallySignedTransaction psbtx(mtx);
bool complete = false; bool complete = false;
const TransactionError err = model->wallet().fillPSBT(SIGHASH_ALL, false /* sign */, true /* bip32derivs */, psbtx, complete); const TransactionError err = model->wallet().fillPSBT(SIGHASH_ALL, false /* sign */, true /* bip32derivs */, psbtx, complete);
@@ -401,12 +406,12 @@ void SendCoinsDialog::on_sendButton_clicked()
Q_EMIT message(tr("PSBT copied"), "Copied to clipboard", CClientUIInterface::MSG_INFORMATION); Q_EMIT message(tr("PSBT copied"), "Copied to clipboard", CClientUIInterface::MSG_INFORMATION);
} else { } else {
// now send the prepared transaction // now send the prepared transaction
WalletModel::SendCoinsReturn sendStatus = model->sendCoins(currentTransaction); WalletModel::SendCoinsReturn sendStatus = model->sendCoins(*m_current_transaction);
// process sendStatus and on error generate message shown to user // process sendStatus and on error generate message shown to user
processSendCoinsReturn(sendStatus); processSendCoinsReturn(sendStatus);
if (sendStatus.status == WalletModel::OK) { if (sendStatus.status == WalletModel::OK) {
Q_EMIT coinsSent(currentTransaction.getWtx()->GetHash()); Q_EMIT coinsSent(m_current_transaction->getWtx()->GetHash());
} else { } else {
send_failure = true; send_failure = true;
} }

View File

@@ -60,6 +60,7 @@ private:
Ui::SendCoinsDialog *ui; Ui::SendCoinsDialog *ui;
ClientModel *clientModel; ClientModel *clientModel;
WalletModel *model; WalletModel *model;
std::unique_ptr<WalletModelTransaction> m_current_transaction;
bool fNewRecipientAllowed; bool fNewRecipientAllowed;
bool fFeeMinimized; bool fFeeMinimized;
const PlatformStyle *platformStyle; const PlatformStyle *platformStyle;
@@ -69,6 +70,8 @@ private:
// Additional parameter msgArg can be used via .arg(msgArg). // Additional parameter msgArg can be used via .arg(msgArg).
void processSendCoinsReturn(const WalletModel::SendCoinsReturn &sendCoinsReturn, const QString &msgArg = QString()); void processSendCoinsReturn(const WalletModel::SendCoinsReturn &sendCoinsReturn, const QString &msgArg = QString());
void minimizeFeeSection(bool fMinimize); void minimizeFeeSection(bool fMinimize);
// Format confirmation message
bool PrepareSendText(QString& question_string, QString& informative_text, QString& detailed_text);
void updateFeeMinimizedLabel(); void updateFeeMinimizedLabel();
// Update the passed in CCoinControl with state from the GUI // Update the passed in CCoinControl with state from the GUI
void updateCoinControlState(CCoinControl& ctrl); void updateCoinControlState(CCoinControl& ctrl);