Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions doc/release-notes-911.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
GUI Changes
---

The Overview page now displays a "On hold:" balance row showing funds that would be spent if wallet transactions currently outside the mempool were to confirm. This row is only shown when non-mempool wallet transactions are present.
11 changes: 7 additions & 4 deletions src/qt/bitcoinunits.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,6 @@ QString BitcoinUnits::format(Unit unit, const CAmount& nIn, bool fPlus, Separato
qint64 n_abs = (n > 0 ? n : -n);
qint64 quotient = n_abs / coin;
QString quotient_str = QString::number(quotient);
if (justify) {
quotient_str = quotient_str.rightJustified(MAX_DIGITS_BTC - num_decimals, ' ');
}

// Use SI-style thin space separators as these are locale independent and can't be
// confused with the decimal marker.
Expand All @@ -110,6 +107,13 @@ QString BitcoinUnits::format(Unit unit, const CAmount& nIn, bool fPlus, Separato
else if (fPlus && n > 0)
quotient_str.insert(0, '+');

// Right-justify after the sign is prepended, so that the sign stays
// adjacent to the most significant digit rather than being separated
// from it by the justification padding.
if (justify) {
quotient_str = quotient_str.rightJustified(MAX_DIGITS_BTC - num_decimals, ' ');
}

if (num_decimals > 0) {
qint64 remainder = n_abs % coin;
QString remainder_str = QString::number(remainder).rightJustified(num_decimals, '0');
Expand Down Expand Up @@ -142,7 +146,6 @@ QString BitcoinUnits::formatHtmlWithUnit(Unit unit, const CAmount& amount, bool

QString BitcoinUnits::formatWithPrivacy(Unit unit, const CAmount& amount, SeparatorStyle separators, bool privacy)
{
assert(amount >= 0);
QString value;
if (privacy) {
value = format(unit, 0, false, separators, true).replace('0', '#');
Expand Down
32 changes: 29 additions & 3 deletions src/qt/forms/overviewpage.ui
Original file line number Diff line number Diff line change
Expand Up @@ -130,14 +130,14 @@
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<item row="4" column="0" colspan="2">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="4" column="0">
<item row="5" column="0">
<widget class="QLabel" name="labelTotalText">
<property name="text">
<string>Total:</string>
Expand Down Expand Up @@ -183,7 +183,33 @@
</property>
</widget>
</item>
<item row="4" column="1">
<item row="3" column="1">
<widget class="QLabel" name="labelNonMempool">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
</property>
<property name="toolTip">
<string>Balance for wallet transactions that currently don't fit node's mempool policies</string>
</property>
<property name="text">
<string notr="true">0.00000000 BTC</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="labelNonMempoolText">
<property name="text">
<string>On hold:</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLabel" name="labelTotal">
<property name="cursor">
<cursorShape>IBeamCursor</cursorShape>
Expand Down
12 changes: 11 additions & 1 deletion src/qt/overviewpage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,13 +190,22 @@ void OverviewPage::setBalance(const interfaces::WalletBalances& balances)
ui->labelBalance->setText(BitcoinUnits::formatWithPrivacy(unit, balances.balance, BitcoinUnits::SeparatorStyle::ALWAYS, m_privacy));
ui->labelUnconfirmed->setText(BitcoinUnits::formatWithPrivacy(unit, balances.unconfirmed_balance, BitcoinUnits::SeparatorStyle::ALWAYS, m_privacy));
ui->labelImmature->setText(BitcoinUnits::formatWithPrivacy(unit, balances.immature_balance, BitcoinUnits::SeparatorStyle::ALWAYS, m_privacy));
ui->labelTotal->setText(BitcoinUnits::formatWithPrivacy(unit, balances.balance + balances.unconfirmed_balance + balances.immature_balance, BitcoinUnits::SeparatorStyle::ALWAYS, m_privacy));
ui->labelNonMempool->setText(BitcoinUnits::formatWithPrivacy(unit, balances.nonmempool_balance, BitcoinUnits::SeparatorStyle::ALWAYS, m_privacy));
ui->labelNonMempool->setStyleSheet("QLabel { color: " + COLOR_NEGATIVE.name() + "; }");
ui->labelTotal->setText(BitcoinUnits::formatWithPrivacy(unit, balances.balance + balances.unconfirmed_balance + balances.immature_balance + balances.nonmempool_balance, BitcoinUnits::SeparatorStyle::ALWAYS, m_privacy));
// only show immature (newly mined) balance if it's non-zero, so as not to complicate things
// for the non-mining users
bool showImmature = balances.immature_balance != 0;

ui->labelImmature->setVisible(showImmature);
ui->labelImmatureText->setVisible(showImmature);

// likewise for non-mempool balances
Assert(balances.nonmempool_balance <= 0);
bool showNonMempool = balances.nonmempool_balance < 0;

ui->labelNonMempool->setVisible(showNonMempool);
ui->labelNonMempoolText->setVisible(showNonMempool);
}

void OverviewPage::setClientModel(ClientModel *model)
Expand Down Expand Up @@ -296,5 +305,6 @@ void OverviewPage::setMonospacedFont(const QFont& f)
ui->labelBalance->setFont(f);
ui->labelUnconfirmed->setFont(f);
ui->labelImmature->setFont(f);
ui->labelNonMempool->setFont(f);
ui->labelTotal->setFont(f);
}
16 changes: 15 additions & 1 deletion src/qt/test/wallettests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,21 @@ void TestGUI(interfaces::Node& node, const std::shared_ptr<CWallet>& wallet)
OverviewPage overviewPage(platformStyle.get());
overviewPage.setWalletModel(&walletModel);
walletModel.pollBalanceChanged(); // Manual balance polling update
CompareBalance(walletModel, walletModel.wallet().getBalance(), overviewPage.findChild<QLabel*>("labelBalance"));
CompareBalance(walletModel, walletModel.wallet().getBalances().balance, overviewPage.findChild<QLabel*>("labelBalance"));

// Test non-mempool balance display
overviewPage.show();
interfaces::WalletBalances nonmempool_balances;
nonmempool_balances.balance = walletModel.wallet().getBalances().balance;
nonmempool_balances.nonmempool_balance = -50000;
overviewPage.setBalance(nonmempool_balances);
QVERIFY(overviewPage.findChild<QLabel*>("labelNonMempool")->isVisible());
QVERIFY(overviewPage.findChild<QLabel*>("labelNonMempoolText")->isVisible());
CompareBalance(walletModel, -50000, overviewPage.findChild<QLabel*>("labelNonMempool"));
nonmempool_balances.nonmempool_balance = 0;
overviewPage.setBalance(nonmempool_balances);
QVERIFY(!overviewPage.findChild<QLabel*>("labelNonMempool")->isVisible());
QVERIFY(!overviewPage.findChild<QLabel*>("labelNonMempoolText")->isVisible());

// Check Request Payment button
ReceiveCoinsDialog receiveCoinsDialog(platformStyle.get());
Expand Down
2 changes: 1 addition & 1 deletion src/wallet/interfaces.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ class WalletImpl : public Wallet
}
WalletBalances getBalances() override
{
const auto bal = GetBalance(*m_wallet);
const auto bal = GetBalance(*m_wallet, /*min_depth=*/0, /*avoid_reuse=*/true, /*include_nonmempool=*/true);
WalletBalances result;
result.balance = bal.m_mine_trusted;
result.unconfirmed_balance = bal.m_mine_untrusted_pending;
Expand Down
Loading