Changeset View
Changeset View
Standalone View
Standalone View
src/qt/sendcoinsdialog.cpp
Show All 24 Lines | |||||
#include "wallet/wallet.h" | #include "wallet/wallet.h" | ||||
#include <QMessageBox> | #include <QMessageBox> | ||||
#include <QScrollBar> | #include <QScrollBar> | ||||
#include <QSettings> | #include <QSettings> | ||||
#include <QTextDocument> | #include <QTextDocument> | ||||
#include <QTimer> | #include <QTimer> | ||||
static const std::array<int, 9> confTargets = { | |||||
{2, 4, 6, 12, 24, 48, 144, 504, 1008}}; | |||||
int getConfTargetForIndex(int index) { | |||||
if (index + 1 > static_cast<int>(confTargets.size())) { | |||||
return confTargets.back(); | |||||
} | |||||
if (index < 0) { | |||||
return confTargets[0]; | |||||
} | |||||
return confTargets[index]; | |||||
} | |||||
int getIndexForConfTarget(int target) { | |||||
for (unsigned int i = 0; i < confTargets.size(); i++) { | |||||
if (confTargets[i] >= target) { | |||||
return i; | |||||
} | |||||
} | |||||
return confTargets.size() - 1; | |||||
} | |||||
SendCoinsDialog::SendCoinsDialog(const PlatformStyle *_platformStyle, | SendCoinsDialog::SendCoinsDialog(const PlatformStyle *_platformStyle, | ||||
QWidget *parent) | QWidget *parent) | ||||
: QDialog(parent), ui(new Ui::SendCoinsDialog), clientModel(0), model(0), | : QDialog(parent), ui(new Ui::SendCoinsDialog), clientModel(0), model(0), | ||||
fNewRecipientAllowed(true), fFeeMinimized(true), | fNewRecipientAllowed(true), fFeeMinimized(true), | ||||
platformStyle(_platformStyle) { | platformStyle(_platformStyle) { | ||||
ui->setupUi(this); | ui->setupUi(this); | ||||
if (!_platformStyle->getImagesOnButtons()) { | if (!_platformStyle->getImagesOnButtons()) { | ||||
▲ Show 20 Lines • Show All 75 Lines • ▼ Show 20 Lines | if (!settings.contains("nCustomFeeRadio") && | ||||
settings.value("nTransactionFee").toLongLong() > 0) { | settings.value("nTransactionFee").toLongLong() > 0) { | ||||
// total at least | // total at least | ||||
settings.setValue("nCustomFeeRadio", 1); | settings.setValue("nCustomFeeRadio", 1); | ||||
} | } | ||||
if (!settings.contains("nCustomFeeRadio")) { | if (!settings.contains("nCustomFeeRadio")) { | ||||
// per kilobyte | // per kilobyte | ||||
settings.setValue("nCustomFeeRadio", 0); | settings.setValue("nCustomFeeRadio", 0); | ||||
} | } | ||||
if (!settings.contains("nSmartFeeSliderPosition")) { | |||||
settings.setValue("nSmartFeeSliderPosition", 0); | |||||
} | |||||
if (!settings.contains("nTransactionFee")) { | if (!settings.contains("nTransactionFee")) { | ||||
settings.setValue("nTransactionFee", | settings.setValue("nTransactionFee", | ||||
qint64(DEFAULT_TRANSACTION_FEE / SATOSHI)); | qint64(DEFAULT_TRANSACTION_FEE / SATOSHI)); | ||||
} | } | ||||
if (!settings.contains("fPayOnlyMinFee")) { | if (!settings.contains("fPayOnlyMinFee")) { | ||||
settings.setValue("fPayOnlyMinFee", false); | settings.setValue("fPayOnlyMinFee", false); | ||||
} | } | ||||
ui->groupFee->setId(ui->radioSmartFee, 0); | ui->groupFee->setId(ui->radioSmartFee, 0); | ||||
▲ Show 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | if (_model && _model->getOptionsModel()) { | ||||
connect(_model->getOptionsModel(), | connect(_model->getOptionsModel(), | ||||
SIGNAL(coinControlFeaturesChanged(bool)), this, | SIGNAL(coinControlFeaturesChanged(bool)), this, | ||||
SLOT(coinControlFeatureChanged(bool))); | SLOT(coinControlFeatureChanged(bool))); | ||||
ui->frameCoinControl->setVisible( | ui->frameCoinControl->setVisible( | ||||
_model->getOptionsModel()->getCoinControlFeatures()); | _model->getOptionsModel()->getCoinControlFeatures()); | ||||
coinControlUpdateLabels(); | coinControlUpdateLabels(); | ||||
// fee section | // fee section | ||||
for (const int n : confTargets) { | |||||
ui->confTargetSelector->addItem( | |||||
tr("%1 (%2 blocks)") | |||||
.arg(GUIUtil::formatNiceTimeOffset( | |||||
n * Params().GetConsensus().nPowTargetSpacing)) | |||||
.arg(n)); | |||||
} | |||||
connect(ui->confTargetSelector, SIGNAL(currentIndexChanged(int)), this, | |||||
SLOT(updateSmartFeeLabel())); | |||||
connect(ui->confTargetSelector, SIGNAL(currentIndexChanged(int)), this, | |||||
SLOT(updateGlobalFeeVariables())); | |||||
connect(ui->confTargetSelector, SIGNAL(currentIndexChanged(int)), this, | |||||
SLOT(coinControlUpdateLabels())); | |||||
connect(ui->groupFee, SIGNAL(buttonClicked(int)), this, | connect(ui->groupFee, SIGNAL(buttonClicked(int)), this, | ||||
SLOT(updateFeeSectionControls())); | SLOT(updateFeeSectionControls())); | ||||
connect(ui->groupFee, SIGNAL(buttonClicked(int)), this, | connect(ui->groupFee, SIGNAL(buttonClicked(int)), this, | ||||
SLOT(updateGlobalFeeVariables())); | SLOT(updateGlobalFeeVariables())); | ||||
connect(ui->groupFee, SIGNAL(buttonClicked(int)), this, | connect(ui->groupFee, SIGNAL(buttonClicked(int)), this, | ||||
SLOT(coinControlUpdateLabels())); | SLOT(coinControlUpdateLabels())); | ||||
connect(ui->groupCustomFee, SIGNAL(buttonClicked(int)), this, | connect(ui->groupCustomFee, SIGNAL(buttonClicked(int)), this, | ||||
SLOT(updateGlobalFeeVariables())); | SLOT(updateGlobalFeeVariables())); | ||||
Show All 13 Lines | if (_model && _model->getOptionsModel()) { | ||||
SLOT(coinControlUpdateLabels())); | SLOT(coinControlUpdateLabels())); | ||||
ui->customFee->setSingleStep(GetMinimumFee(1000, 2, g_mempool)); | ui->customFee->setSingleStep(GetMinimumFee(1000, 2, g_mempool)); | ||||
updateFeeSectionControls(); | updateFeeSectionControls(); | ||||
updateMinFeeLabel(); | updateMinFeeLabel(); | ||||
updateSmartFeeLabel(); | updateSmartFeeLabel(); | ||||
updateGlobalFeeVariables(); | updateGlobalFeeVariables(); | ||||
// set the smartfee-sliders default value (wallets default conf.target | // Cleanup old confirmation target related settings | ||||
// or last stored value) | // TODO: Remove these in 0.20 | ||||
QSettings settings; | QSettings settings; | ||||
if (settings.value("nSmartFeeSliderPosition").toInt() != 0) { | if (settings.value("nSmartFeeSliderPosition").toInt() != 0) { | ||||
// migrate nSmartFeeSliderPosition to nConfTarget | |||||
// nConfTarget is available since 0.18.7 (replaced | |||||
// nSmartFeeSliderPosition) 25 == old slider range | |||||
int nConfirmTarget = | |||||
25 - settings.value("nSmartFeeSliderPosition").toInt(); | |||||
settings.setValue("nConfTarget", nConfirmTarget); | |||||
settings.remove("nSmartFeeSliderPosition"); | settings.remove("nSmartFeeSliderPosition"); | ||||
} | } | ||||
if (settings.value("nConfTarget").toInt() == 0) { | if (settings.value("nConfTarget").toInt() != 0) { | ||||
ui->confTargetSelector->setCurrentIndex( | settings.remove("nConfTarget"); | ||||
getIndexForConfTarget(model->getDefaultConfirmTarget())); | |||||
} else { | |||||
ui->confTargetSelector->setCurrentIndex( | |||||
getIndexForConfTarget(settings.value("nConfTarget").toInt())); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
SendCoinsDialog::~SendCoinsDialog() { | SendCoinsDialog::~SendCoinsDialog() { | ||||
QSettings settings; | QSettings settings; | ||||
settings.setValue("fFeeSectionMinimized", fFeeMinimized); | settings.setValue("fFeeSectionMinimized", fFeeMinimized); | ||||
settings.setValue("nFeeRadio", ui->groupFee->checkedId()); | settings.setValue("nFeeRadio", ui->groupFee->checkedId()); | ||||
settings.setValue("nCustomFeeRadio", ui->groupCustomFee->checkedId()); | settings.setValue("nCustomFeeRadio", ui->groupCustomFee->checkedId()); | ||||
settings.setValue( | |||||
"nConfTarget", | |||||
getConfTargetForIndex(ui->confTargetSelector->currentIndex())); | |||||
settings.setValue("nTransactionFee", | settings.setValue("nTransactionFee", | ||||
qint64(ui->customFee->value() / SATOSHI)); | qint64(ui->customFee->value() / SATOSHI)); | ||||
settings.setValue("fPayOnlyMinFee", ui->checkBoxMinimumFee->isChecked()); | settings.setValue("fPayOnlyMinFee", ui->checkBoxMinimumFee->isChecked()); | ||||
delete ui; | delete ui; | ||||
} | } | ||||
void SendCoinsDialog::on_sendButton_clicked() { | void SendCoinsDialog::on_sendButton_clicked() { | ||||
Show All 33 Lines | void SendCoinsDialog::on_sendButton_clicked() { | ||||
WalletModel::SendCoinsReturn prepareStatus; | WalletModel::SendCoinsReturn prepareStatus; | ||||
// Always use a CCoinControl instance, use the CoinControlDialog instance if | // Always use a CCoinControl instance, use the CoinControlDialog instance if | ||||
// CoinControl has been enabled | // CoinControl has been enabled | ||||
CCoinControl ctrl; | CCoinControl ctrl; | ||||
if (model->getOptionsModel()->getCoinControlFeatures()) { | if (model->getOptionsModel()->getCoinControlFeatures()) { | ||||
ctrl = *CoinControlDialog::coinControl; | ctrl = *CoinControlDialog::coinControl; | ||||
} | } | ||||
if (ui->radioSmartFee->isChecked()) { | |||||
ctrl.nConfirmTarget = | |||||
getConfTargetForIndex(ui->confTargetSelector->currentIndex()); | |||||
} else { | |||||
ctrl.nConfirmTarget = 0; | |||||
} | |||||
prepareStatus = model->prepareTransaction(currentTransaction, &ctrl); | prepareStatus = model->prepareTransaction(currentTransaction, &ctrl); | ||||
// process prepareStatus and on error generate message shown to user | // process prepareStatus and on error generate message shown to user | ||||
processSendCoinsReturn( | processSendCoinsReturn( | ||||
prepareStatus, | prepareStatus, | ||||
BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), | BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), | ||||
currentTransaction.getTransactionFee())); | currentTransaction.getTransactionFee())); | ||||
▲ Show 20 Lines • Show All 372 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
void SendCoinsDialog::setMinimumFee() { | void SendCoinsDialog::setMinimumFee() { | ||||
ui->radioCustomPerKilobyte->setChecked(true); | ui->radioCustomPerKilobyte->setChecked(true); | ||||
ui->customFee->setValue(GetMinimumFee(1000, 2, g_mempool)); | ui->customFee->setValue(GetMinimumFee(1000, 2, g_mempool)); | ||||
} | } | ||||
void SendCoinsDialog::updateFeeSectionControls() { | void SendCoinsDialog::updateFeeSectionControls() { | ||||
ui->confTargetSelector->setEnabled(ui->radioSmartFee->isChecked()); | |||||
ui->labelSmartFee->setEnabled(ui->radioSmartFee->isChecked()); | ui->labelSmartFee->setEnabled(ui->radioSmartFee->isChecked()); | ||||
ui->labelSmartFee2->setEnabled(ui->radioSmartFee->isChecked()); | ui->labelSmartFee2->setEnabled(ui->radioSmartFee->isChecked()); | ||||
ui->labelSmartFee3->setEnabled(ui->radioSmartFee->isChecked()); | |||||
ui->labelFeeEstimation->setEnabled(ui->radioSmartFee->isChecked()); | ui->labelFeeEstimation->setEnabled(ui->radioSmartFee->isChecked()); | ||||
ui->checkBoxMinimumFee->setEnabled(ui->radioCustomFee->isChecked()); | ui->checkBoxMinimumFee->setEnabled(ui->radioCustomFee->isChecked()); | ||||
ui->labelMinFeeWarning->setEnabled(ui->radioCustomFee->isChecked()); | ui->labelMinFeeWarning->setEnabled(ui->radioCustomFee->isChecked()); | ||||
ui->radioCustomPerKilobyte->setEnabled( | ui->radioCustomPerKilobyte->setEnabled( | ||||
ui->radioCustomFee->isChecked() && | ui->radioCustomFee->isChecked() && | ||||
!ui->checkBoxMinimumFee->isChecked()); | !ui->checkBoxMinimumFee->isChecked()); | ||||
ui->customFee->setEnabled(ui->radioCustomFee->isChecked() && | ui->customFee->setEnabled(ui->radioCustomFee->isChecked() && | ||||
!ui->checkBoxMinimumFee->isChecked()); | !ui->checkBoxMinimumFee->isChecked()); | ||||
Show All 34 Lines | void SendCoinsDialog::updateMinFeeLabel() { | ||||
} | } | ||||
} | } | ||||
void SendCoinsDialog::updateSmartFeeLabel() { | void SendCoinsDialog::updateSmartFeeLabel() { | ||||
if (!model || !model->getOptionsModel()) { | if (!model || !model->getOptionsModel()) { | ||||
return; | return; | ||||
} | } | ||||
int nBlocksToConfirm = | int nBlocksToConfirm = 1; | ||||
getConfTargetForIndex(ui->confTargetSelector->currentIndex()); | |||||
CFeeRate feeRate = g_mempool.estimateFee(nBlocksToConfirm); | CFeeRate feeRate = g_mempool.estimateFee(nBlocksToConfirm); | ||||
// not enough data => minfee | // not enough data => minfee | ||||
if (feeRate <= CFeeRate(Amount::zero())) { | if (feeRate <= CFeeRate(Amount::zero())) { | ||||
ui->labelSmartFee->setText( | ui->labelSmartFee->setText( | ||||
BitcoinUnits::formatWithUnit( | BitcoinUnits::formatWithUnit( | ||||
model->getOptionsModel()->getDisplayUnit(), | model->getOptionsModel()->getDisplayUnit(), | ||||
std::max(CWallet::fallbackFee.GetFeePerK(), | std::max(CWallet::fallbackFee.GetFeePerK(), | ||||
GetMinimumFee(1000, 2, g_mempool))) + | GetMinimumFee(1000, 2, g_mempool))) + | ||||
▲ Show 20 Lines • Show All 233 Lines • Show Last 20 Lines |