From c1c9d5b415fda7d1310c23857e57d98ac14c3063 Mon Sep 17 00:00:00 2001 From: Cozz Lovan Date: Sun, 2 Nov 2014 00:14:47 +0100 Subject: [Qt] Add Smartfee to GUI --- src/qt/coincontroldialog.cpp | 95 +++++++++++++++++++++++++------------------- 1 file changed, 54 insertions(+), 41 deletions(-) (limited to 'src/qt/coincontroldialog.cpp') diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index ba0febe546..85b43b7b1f 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -130,10 +131,22 @@ CoinControlDialog::CoinControlDialog(QWidget *parent) : // default view is sorted by amount desc sortView(COLUMN_AMOUNT_INT64, Qt::DescendingOrder); + + // restore list mode and sortorder as a convenience feature + QSettings settings; + if (settings.contains("nCoinControlMode") && !settings.value("nCoinControlMode").toBool()) + ui->radioTreeMode->click(); + if (settings.contains("nCoinControlSortColumn") && settings.contains("nCoinControlSortOrder")) + sortView(settings.value("nCoinControlSortColumn").toInt(), ((Qt::SortOrder)settings.value("nCoinControlSortOrder").toInt())); } CoinControlDialog::~CoinControlDialog() { + QSettings settings; + settings.setValue("nCoinControlMode", ui->radioListMode->isChecked()); + settings.setValue("nCoinControlSortColumn", sortColumn); + settings.setValue("nCoinControlSortOrder", (int)sortOrder); + delete ui; } @@ -290,19 +303,19 @@ void CoinControlDialog::clipboardAmount() // copy label "Fee" to clipboard void CoinControlDialog::clipboardFee() { - GUIUtil::setClipboard(ui->labelCoinControlFee->text().left(ui->labelCoinControlFee->text().indexOf(" "))); + GUIUtil::setClipboard(ui->labelCoinControlFee->text().left(ui->labelCoinControlFee->text().indexOf(" ")).replace("~", "")); } // copy label "After fee" to clipboard void CoinControlDialog::clipboardAfterFee() { - GUIUtil::setClipboard(ui->labelCoinControlAfterFee->text().left(ui->labelCoinControlAfterFee->text().indexOf(" "))); + GUIUtil::setClipboard(ui->labelCoinControlAfterFee->text().left(ui->labelCoinControlAfterFee->text().indexOf(" ")).replace("~", "")); } // copy label "Bytes" to clipboard void CoinControlDialog::clipboardBytes() { - GUIUtil::setClipboard(ui->labelCoinControlBytes->text()); + GUIUtil::setClipboard(ui->labelCoinControlBytes->text().replace("~", "")); } // copy label "Priority" to clipboard @@ -320,7 +333,7 @@ void CoinControlDialog::clipboardLowOutput() // copy label "Change" to clipboard void CoinControlDialog::clipboardChange() { - GUIUtil::setClipboard(ui->labelCoinControlChange->text().left(ui->labelCoinControlChange->text().indexOf(" "))); + GUIUtil::setClipboard(ui->labelCoinControlChange->text().left(ui->labelCoinControlChange->text().indexOf(" ")).replace("~", "")); } // treeview: sort @@ -402,26 +415,22 @@ void CoinControlDialog::viewItemChanged(QTreeWidgetItem* item, int column) } // return human readable label for priority number -QString CoinControlDialog::getPriorityLabel(const CTxMemPool& pool, double dPriority) +QString CoinControlDialog::getPriorityLabel(double dPriority, double mempoolEstimatePriority) { - // confirmations -> textual description - typedef std::map PriorityDescription; - const static PriorityDescription priorityDescriptions = boost::assign::map_list_of - (1, tr("highest"))(2, tr("higher"))(3, tr("high")) - (5, tr("medium-high"))(6, tr("medium")) - (10, tr("low-medium"))(15, tr("low")) - (20, tr("lower")); - - BOOST_FOREACH(const PriorityDescription::value_type& i, priorityDescriptions) - { - double p = mempool.estimatePriority(i.first); - if (p > 0 && dPriority >= p) return i.second; - } - // Note: if mempool hasn't accumulated enough history (estimatePriority - // returns -1) we're conservative and classify as "lowest" - if (mempool.estimatePriority(nTxConfirmTarget) <= 0 && AllowFree(dPriority)) - return ">=" + tr("medium"); - return tr("lowest"); + double dPriorityMedium = mempoolEstimatePriority; + + if (dPriorityMedium <= 0) + dPriorityMedium = AllowFreeThreshold(); // not enough data, back to hard-coded + + if (dPriority / 1000000 > dPriorityMedium) return tr("highest"); + else if (dPriority / 100000 > dPriorityMedium) return tr("higher"); + else if (dPriority / 10000 > dPriorityMedium) return tr("high"); + else if (dPriority / 1000 > dPriorityMedium) return tr("medium-high"); + else if (dPriority > dPriorityMedium) return tr("medium"); + else if (dPriority * 10 > dPriorityMedium) return tr("low-medium"); + else if (dPriority * 100 > dPriorityMedium) return tr("low"); + else if (dPriority * 1000 > dPriorityMedium) return tr("lower"); + else return tr("lowest"); } // shows count of locked unspent outputs @@ -470,6 +479,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) double dPriorityInputs = 0; unsigned int nQuantity = 0; int nQuantityUncompressed = 0; + bool fAllowFree = false; vector vCoinControl; vector vOutputs; @@ -522,24 +532,22 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) nBytes = nBytesInputs + ((CoinControlDialog::payAmounts.size() > 0 ? CoinControlDialog::payAmounts.size() + 1 : 2) * 34) + 10; // always assume +1 output for change here // Priority + double mempoolEstimatePriority = mempool.estimatePriority(nTxConfirmTarget); dPriority = dPriorityInputs / (nBytes - nBytesInputs + (nQuantityUncompressed * 29)); // 29 = 180 - 151 (uncompressed public keys are over the limit. max 151 bytes of the input are ignored for priority) - sPriorityLabel = CoinControlDialog::getPriorityLabel(mempool, dPriority); + sPriorityLabel = CoinControlDialog::getPriorityLabel(dPriority, mempoolEstimatePriority); - // Voluntary Fee - nPayFee = payTxFee.GetFee(max((unsigned int)1000, nBytes)); + // Fee + nPayFee = CWallet::GetMinimumFee(nBytes, nTxConfirmTarget, mempool); - // Min Fee - if (nPayFee == 0) - { - nPayFee = CWallet::GetMinimumFee(nBytes, nTxConfirmTarget, mempool); - - double dPriorityNeeded = mempool.estimatePriority(nTxConfirmTarget); - if (dPriorityNeeded <= 0 && !AllowFree(dPriority)) // not enough mempool history: never send free - dPriorityNeeded = std::numeric_limits::max(); + // Allow free? + double dPriorityNeeded = mempoolEstimatePriority; + if (dPriorityNeeded <= 0) + dPriorityNeeded = AllowFreeThreshold(); // not enough data, back to hard-coded + fAllowFree = (dPriority >= dPriorityNeeded); - if (nBytes <= MAX_FREE_TRANSACTION_CREATE_SIZE && dPriority >= dPriorityNeeded) + if (fSendFreeTransactions) + if (fAllowFree && nBytes <= MAX_FREE_TRANSACTION_CREATE_SIZE) nPayFee = 0; - } if (nPayAmount > 0) { @@ -595,7 +603,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) l6->setText(sPriorityLabel); // Priority l7->setText(fDust ? tr("yes") : tr("no")); // Dust l8->setText(BitcoinUnits::formatWithUnit(nDisplayUnit, nChange)); // Change - if (nPayFee > 0) + if (nPayFee > 0 && !(payTxFee.GetFeePerK() > 0 && fPayAtLeastCustomFee && nBytes < 1000)) { l3->setText("~" + l3->text()); l4->setText("~" + l4->text()); @@ -605,7 +613,7 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) // turn labels "red" l5->setStyleSheet((nBytes >= MAX_FREE_TRANSACTION_CREATE_SIZE) ? "color:red;" : "");// Bytes >= 1000 - l6->setStyleSheet((dPriority > 0 && !AllowFree(dPriority)) ? "color:red;" : ""); // Priority < "medium" + l6->setStyleSheet((dPriority > 0 && !fAllowFree) ? "color:red;" : ""); // Priority < "medium" l7->setStyleSheet((fDust) ? "color:red;" : ""); // Dust = "yes" // tool tips @@ -620,7 +628,11 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) QString toolTip3 = tr("This label turns red, if any recipient receives an amount smaller than %1.").arg(BitcoinUnits::formatWithUnit(nDisplayUnit, ::minRelayTxFee.GetFee(546))); // how many satoshis the estimated fee can vary per byte we guess wrong - double dFeeVary = (double)std::max(CWallet::minTxFee.GetFeePerK(), std::max(payTxFee.GetFeePerK(), mempool.estimateFee(nTxConfirmTarget).GetFeePerK())) / 1000; + double dFeeVary; + if (payTxFee.GetFeePerK() > 0) + dFeeVary = (double)std::max(CWallet::minTxFee.GetFeePerK(), payTxFee.GetFeePerK()) / 1000; + else + dFeeVary = (double)std::max(CWallet::minTxFee.GetFeePerK(), mempool.estimateFee(nTxConfirmTarget).GetFeePerK()) / 1000; QString toolTip4 = tr("Can vary +/- %1 satoshi(s) per input.").arg(dFeeVary); l3->setToolTip(toolTip4); @@ -656,6 +668,7 @@ void CoinControlDialog::updateView() QFlags flgTristate = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsTristate; int nDisplayUnit = model->getOptionsModel()->getDisplayUnit(); + double mempoolEstimatePriority = mempool.estimatePriority(nTxConfirmTarget); map > mapCoins; model->listCoins(mapCoins); @@ -745,7 +758,7 @@ void CoinControlDialog::updateView() // priority double dPriority = ((double)out.tx->vout[out.i].nValue / (nInputSize + 78)) * (out.nDepth+1); // 78 = 2 * 34 + 10 - itemOutput->setText(COLUMN_PRIORITY, CoinControlDialog::getPriorityLabel(mempool, dPriority)); + itemOutput->setText(COLUMN_PRIORITY, CoinControlDialog::getPriorityLabel(dPriority, mempoolEstimatePriority)); itemOutput->setText(COLUMN_PRIORITY_INT64, strPad(QString::number((int64_t)dPriority), 20, " ")); dPrioritySum += (double)out.tx->vout[out.i].nValue * (out.nDepth+1); nInputSum += nInputSize; @@ -778,7 +791,7 @@ void CoinControlDialog::updateView() itemWalletAddress->setText(COLUMN_CHECKBOX, "(" + QString::number(nChildren) + ")"); itemWalletAddress->setText(COLUMN_AMOUNT, BitcoinUnits::format(nDisplayUnit, nSum)); itemWalletAddress->setText(COLUMN_AMOUNT_INT64, strPad(QString::number(nSum), 15, " ")); - itemWalletAddress->setText(COLUMN_PRIORITY, CoinControlDialog::getPriorityLabel(mempool, dPrioritySum)); + itemWalletAddress->setText(COLUMN_PRIORITY, CoinControlDialog::getPriorityLabel(dPrioritySum, mempoolEstimatePriority)); itemWalletAddress->setText(COLUMN_PRIORITY_INT64, strPad(QString::number((int64_t)dPrioritySum), 20, " ")); } } -- cgit v1.2.3