Merge bitcoin-core/gui#556: refactor: Make BitcoinUnits::Unit a scoped enum

0e5dedbc9e qt/wallettests: sort includes (William Casarin)
0554251d66 qt: Skip displayUnitChanged signal if unit is not actually changed (Hennadii Stepanov)
ffbc2fe459 qt, refactor: Remove default cases for scoped enum (Hennadii Stepanov)
152d5bad50 qt, refactor: Remove BitcoinUnits::valid function (Hennadii Stepanov)
aa23960fdf qt, refactor: Make BitcoinUnits::Unit a scoped enum (Hennadii Stepanov)
75832fdc37 qt: Use QVariant instead of int for BitcoinUnit in QSettings (Hennadii Stepanov)

Pull request description:

  This is a rebased version of #60

  Since Qt 5.5 there are [means](https://doc.qt.io/qt-5/qobject.html#Q_ENUM) to register an enum type with the meta-object system (such enum still lacks an ability to interact with [QSettings::setValue()](https://doc.qt.io/qt-5/qsettings.html#setValue) and [QSettings::value()](https://doc.qt.io/qt-5/qsettings.html#value) without defined stream operators).

  In order to reduce global namespace polluting and to force strong type checking, this PR makes BitcoinUnits::Unit a scoped enum (typedef BitcoinUnits::Unit BitcoinUnit;).

  No behavior change.

ACKs for top commit:
  jonatack:
    ACK 0e5dedbc9e, review and debug build of each commit after rebase on current master, lightly tested running the GUI, changing units a few times, and verifying persistence after restarting
  promag:
    Code review ACK 0e5dedbc9e

Tree-SHA512: 39ec0d7e4f0b9b25be287888121a8db6b282339674e37ec3a3554da63a9e22d6fe079e8310ca289b2a0356a19b3c7e55afa17d09dd34e0f222177f603bb053a3
This commit is contained in:
Hennadii Stepanov committed 2022-04-15 11:51:22 +02:00
commit 72477ebb11
19 files changed
+188 -157

No files matched your search

+2
View File
@@ -95,6 +95,8 @@ static void RegisterMetaTypes()
qRegisterMetaType<std::function<void()>>("std::function<void()>"); qRegisterMetaType<std::function<void()>>("std::function<void()>");
qRegisterMetaType<QMessageBox::Icon>("QMessageBox::Icon"); qRegisterMetaType<QMessageBox::Icon>("QMessageBox::Icon");
qRegisterMetaType<interfaces::BlockAndHeaderTipInfo>("interfaces::BlockAndHeaderTipInfo"); qRegisterMetaType<interfaces::BlockAndHeaderTipInfo>("interfaces::BlockAndHeaderTipInfo");
qRegisterMetaTypeStreamOperators<BitcoinUnit>("BitcoinUnit");
} }
static QString GetLangTerritory() static QString GetLangTerritory()
+11 -8
View File
@@ -14,6 +14,9 @@
#include <QHBoxLayout> #include <QHBoxLayout>
#include <QKeyEvent> #include <QKeyEvent>
#include <QLineEdit> #include <QLineEdit>
#include <QVariant>
#include <cassert>
/** QSpinBox that uses fixed-point numbers internally and uses our own /** QSpinBox that uses fixed-point numbers internally and uses our own
* formatting/parsing functions. * formatting/parsing functions.
@@ -96,7 +99,7 @@ public:
setValue(val); setValue(val);
} }
void setDisplayUnit(int unit) void setDisplayUnit(BitcoinUnit unit)
{ {
bool valid = false; bool valid = false;
CAmount val = value(&valid); CAmount val = value(&valid);
@@ -122,7 +125,7 @@ public:
const QFontMetrics fm(fontMetrics()); const QFontMetrics fm(fontMetrics());
int h = lineEdit()->minimumSizeHint().height(); int h = lineEdit()->minimumSizeHint().height();
int w = GUIUtil::TextWidth(fm, BitcoinUnits::format(BitcoinUnits::BTC, BitcoinUnits::maxMoney(), false, BitcoinUnits::SeparatorStyle::ALWAYS)); int w = GUIUtil::TextWidth(fm, BitcoinUnits::format(BitcoinUnit::BTC, BitcoinUnits::maxMoney(), false, BitcoinUnits::SeparatorStyle::ALWAYS));
w += 2; // cursor blinking space w += 2; // cursor blinking space
QStyleOptionSpinBox opt; QStyleOptionSpinBox opt;
@@ -148,7 +151,7 @@ public:
} }
private: private:
int currentUnit{BitcoinUnits::BTC}; BitcoinUnit currentUnit{BitcoinUnit::BTC};
CAmount singleStep{CAmount(100000)}; // satoshis CAmount singleStep{CAmount(100000)}; // satoshis
mutable QSize cachedMinimumSizeHint; mutable QSize cachedMinimumSizeHint;
bool m_allow_empty{true}; bool m_allow_empty{true};
@@ -326,14 +329,14 @@ void BitcoinAmountField::unitChanged(int idx)
unit->setToolTip(unit->itemData(idx, Qt::ToolTipRole).toString()); unit->setToolTip(unit->itemData(idx, Qt::ToolTipRole).toString());
// Determine new unit ID // Determine new unit ID
int newUnit = unit->itemData(idx, BitcoinUnits::UnitRole).toInt(); QVariant new_unit = unit->currentData(BitcoinUnits::UnitRole);
assert(new_unit.isValid());
amount->setDisplayUnit(newUnit); amount->setDisplayUnit(new_unit.value<BitcoinUnit>());
} }
void BitcoinAmountField::setDisplayUnit(int newUnit) void BitcoinAmountField::setDisplayUnit(BitcoinUnit new_unit)
{ {
unit->setValue(newUnit); unit->setValue(QVariant::fromValue(new_unit));
} }
void BitcoinAmountField::setSingleStep(const CAmount& step) void BitcoinAmountField::setSingleStep(const CAmount& step)
+2 -1
View File
@@ -6,6 +6,7 @@
#define BITCOIN_QT_BITCOINAMOUNTFIELD_H #define BITCOIN_QT_BITCOINAMOUNTFIELD_H
#include <consensus/amount.h> #include <consensus/amount.h>
#include <qt/bitcoinunits.h>
#include <QWidget> #include <QWidget>
@@ -52,7 +53,7 @@ public:
bool validate(); bool validate();
/** Change unit used to display amount. */ /** Change unit used to display amount. */
void setDisplayUnit(int unit); void setDisplayUnit(BitcoinUnit new_unit);
/** Make field empty and ready for new input. */ /** Make field empty and ready for new input. */
void clear(); void clear();
+6 -7
View File
@@ -1245,7 +1245,7 @@ void BitcoinGUI::showEvent(QShowEvent *event)
} }
#ifdef ENABLE_WALLET #ifdef ENABLE_WALLET
void BitcoinGUI::incomingTransaction(const QString& date, int unit, const CAmount& amount, const QString& type, const QString& address, const QString& label, const QString& walletName) void BitcoinGUI::incomingTransaction(const QString& date, BitcoinUnit unit, const CAmount& amount, const QString& type, const QString& address, const QString& label, const QString& walletName)
{ {
// On new transaction, make an info balloon // On new transaction, make an info balloon
QString msg = tr("Date: %1\n").arg(date) + QString msg = tr("Date: %1\n").arg(date) +
@@ -1496,11 +1496,10 @@ UnitDisplayStatusBarControl::UnitDisplayStatusBarControl(const PlatformStyle *pl
{ {
createContextMenu(); createContextMenu();
setToolTip(tr("Unit to show amounts in. Click to select another unit.")); setToolTip(tr("Unit to show amounts in. Click to select another unit."));
QList<BitcoinUnits::Unit> units = BitcoinUnits::availableUnits(); QList<BitcoinUnit> units = BitcoinUnits::availableUnits();
int max_width = 0; int max_width = 0;
const QFontMetrics fm(font()); const QFontMetrics fm(font());
for (const BitcoinUnits::Unit unit : units) for (const BitcoinUnit unit : units) {
{
max_width = qMax(max_width, GUIUtil::TextWidth(fm, BitcoinUnits::longName(unit))); max_width = qMax(max_width, GUIUtil::TextWidth(fm, BitcoinUnits::longName(unit)));
} }
setMinimumSize(max_width, 0); setMinimumSize(max_width, 0);
@@ -1530,8 +1529,8 @@ void UnitDisplayStatusBarControl::changeEvent(QEvent* e)
void UnitDisplayStatusBarControl::createContextMenu() void UnitDisplayStatusBarControl::createContextMenu()
{ {
menu = new QMenu(this); menu = new QMenu(this);
for (const BitcoinUnits::Unit u : BitcoinUnits::availableUnits()) { for (const BitcoinUnit u : BitcoinUnits::availableUnits()) {
menu->addAction(BitcoinUnits::longName(u))->setData(QVariant(u)); menu->addAction(BitcoinUnits::longName(u))->setData(QVariant::fromValue(u));
} }
connect(menu, &QMenu::triggered, this, &UnitDisplayStatusBarControl::onMenuSelection); connect(menu, &QMenu::triggered, this, &UnitDisplayStatusBarControl::onMenuSelection);
} }
@@ -1552,7 +1551,7 @@ void UnitDisplayStatusBarControl::setOptionsModel(OptionsModel *_optionsModel)
} }
/** When Display Units are changed on OptionsModel it will refresh the display text of the control on the status bar */ /** When Display Units are changed on OptionsModel it will refresh the display text of the control on the status bar */
void UnitDisplayStatusBarControl::updateDisplayUnit(int newUnits) void UnitDisplayStatusBarControl::updateDisplayUnit(BitcoinUnit newUnits)
{ {
setText(BitcoinUnits::longName(newUnits)); setText(BitcoinUnits::longName(newUnits));
} }
+3 -2
View File
@@ -9,6 +9,7 @@
#include <config/bitcoin-config.h> #include <config/bitcoin-config.h>
#endif #endif
#include <qt/bitcoinunits.h>
#include <qt/guiutil.h> #include <qt/guiutil.h>
#include <qt/optionsdialog.h> #include <qt/optionsdialog.h>
@@ -260,7 +261,7 @@ public Q_SLOTS:
bool handlePaymentRequest(const SendCoinsRecipient& recipient); bool handlePaymentRequest(const SendCoinsRecipient& recipient);
/** Show incoming transaction notification for new transactions. */ /** Show incoming transaction notification for new transactions. */
void incomingTransaction(const QString& date, int unit, const CAmount& amount, const QString& type, const QString& address, const QString& label, const QString& walletName); void incomingTransaction(const QString& date, BitcoinUnit unit, const CAmount& amount, const QString& type, const QString& address, const QString& label, const QString& walletName);
#endif // ENABLE_WALLET #endif // ENABLE_WALLET
private: private:
@@ -341,7 +342,7 @@ private:
private Q_SLOTS: private Q_SLOTS:
/** When Display Units are changed on OptionsModel it will refresh the display text of the control on the status bar */ /** When Display Units are changed on OptionsModel it will refresh the display text of the control on the status bar */
void updateDisplayUnit(int newUnits); void updateDisplayUnit(BitcoinUnit newUnits);
/** Tells underlying optionsModel to update its current display unit. */ /** Tells underlying optionsModel to update its current display unit. */
void onMenuSelection(QAction* action); void onMenuSelection(QAction* action);
}; };
+93 -79
View File
@@ -18,94 +18,75 @@ BitcoinUnits::BitcoinUnits(QObject *parent):
{ {
} }
QList<BitcoinUnits::Unit> BitcoinUnits::availableUnits() QList<BitcoinUnit> BitcoinUnits::availableUnits()
{ {
QList<BitcoinUnits::Unit> unitlist; QList<BitcoinUnit> unitlist;
unitlist.append(BTC); unitlist.append(Unit::BTC);
unitlist.append(mBTC); unitlist.append(Unit::mBTC);
unitlist.append(uBTC); unitlist.append(Unit::uBTC);
unitlist.append(SAT); unitlist.append(Unit::SAT);
return unitlist; return unitlist;
} }
bool BitcoinUnits::valid(int unit) QString BitcoinUnits::longName(Unit unit)
{ {
switch(unit) switch (unit) {
{ case Unit::BTC: return QString("BTC");
case BTC: case Unit::mBTC: return QString("mBTC");
case mBTC: case Unit::uBTC: return QString::fromUtf8("µBTC (bits)");
case uBTC: case Unit::SAT: return QString("Satoshi (sat)");
case SAT: } // no default case, so the compiler can warn about missing cases
return true; assert(false);
default:
return false;
}
} }
QString BitcoinUnits::longName(int unit) QString BitcoinUnits::shortName(Unit unit)
{ {
switch(unit) switch (unit) {
{ case Unit::BTC: return longName(unit);
case BTC: return QString("BTC"); case Unit::mBTC: return longName(unit);
case mBTC: return QString("mBTC"); case Unit::uBTC: return QString("bits");
case uBTC: return QString::fromUtf8("µBTC (bits)"); case Unit::SAT: return QString("sat");
case SAT: return QString("Satoshi (sat)"); } // no default case, so the compiler can warn about missing cases
default: return QString("???"); assert(false);
}
} }
QString BitcoinUnits::shortName(int unit) QString BitcoinUnits::description(Unit unit)
{ {
switch(unit) switch (unit) {
{ case Unit::BTC: return QString("Bitcoins");
case uBTC: return QString::fromUtf8("bits"); case Unit::mBTC: return QString("Milli-Bitcoins (1 / 1" THIN_SP_UTF8 "000)");
case SAT: return QString("sat"); case Unit::uBTC: return QString("Micro-Bitcoins (bits) (1 / 1" THIN_SP_UTF8 "000" THIN_SP_UTF8 "000)");
default: return longName(unit); case Unit::SAT: return QString("Satoshi (sat) (1 / 100" THIN_SP_UTF8 "000" THIN_SP_UTF8 "000)");
} } // no default case, so the compiler can warn about missing cases
assert(false);
} }
QString BitcoinUnits::description(int unit) qint64 BitcoinUnits::factor(Unit unit)
{ {
switch(unit) switch (unit) {
{ case Unit::BTC: return 100'000'000;
case BTC: return QString("Bitcoins"); case Unit::mBTC: return 100'000;
case mBTC: return QString("Milli-Bitcoins (1 / 1" THIN_SP_UTF8 "000)"); case Unit::uBTC: return 100;
case uBTC: return QString("Micro-Bitcoins (bits) (1 / 1" THIN_SP_UTF8 "000" THIN_SP_UTF8 "000)"); case Unit::SAT: return 1;
case SAT: return QString("Satoshi (sat) (1 / 100" THIN_SP_UTF8 "000" THIN_SP_UTF8 "000)"); } // no default case, so the compiler can warn about missing cases
default: return QString("???"); assert(false);
}
} }
qint64 BitcoinUnits::factor(int unit) int BitcoinUnits::decimals(Unit unit)
{ {
switch(unit) switch (unit) {
{ case Unit::BTC: return 8;
case BTC: return 100000000; case Unit::mBTC: return 5;
case mBTC: return 100000; case Unit::uBTC: return 2;
case uBTC: return 100; case Unit::SAT: return 0;
case SAT: return 1; } // no default case, so the compiler can warn about missing cases
default: return 100000000; assert(false);
}
} }
int BitcoinUnits::decimals(int unit) QString BitcoinUnits::format(Unit unit, const CAmount& nIn, bool fPlus, SeparatorStyle separators, bool justify)
{
switch(unit)
{
case BTC: return 8;
case mBTC: return 5;
case uBTC: return 2;
case SAT: return 0;
default: return 0;
}
}
QString BitcoinUnits::format(int unit, const CAmount& nIn, bool fPlus, SeparatorStyle separators, bool justify)
{ {
// Note: not using straight sprintf here because we do NOT want // Note: not using straight sprintf here because we do NOT want
// localized number formatting. // localized number formatting.
if(!valid(unit))
return QString(); // Refuse to format invalid unit
qint64 n = (qint64)nIn; qint64 n = (qint64)nIn;
qint64 coin = factor(unit); qint64 coin = factor(unit);
int num_decimals = decimals(unit); int num_decimals = decimals(unit);
@@ -147,19 +128,19 @@ QString BitcoinUnits::format(int unit, const CAmount& nIn, bool fPlus, Separator
// Please take care to use formatHtmlWithUnit instead, when // Please take care to use formatHtmlWithUnit instead, when
// appropriate. // appropriate.
QString BitcoinUnits::formatWithUnit(int unit, const CAmount& amount, bool plussign, SeparatorStyle separators) QString BitcoinUnits::formatWithUnit(Unit unit, const CAmount& amount, bool plussign, SeparatorStyle separators)
{ {
return format(unit, amount, plussign, separators) + QString(" ") + shortName(unit); return format(unit, amount, plussign, separators) + QString(" ") + shortName(unit);
} }
QString BitcoinUnits::formatHtmlWithUnit(int unit, const CAmount& amount, bool plussign, SeparatorStyle separators) QString BitcoinUnits::formatHtmlWithUnit(Unit unit, const CAmount& amount, bool plussign, SeparatorStyle separators)
{ {
QString str(formatWithUnit(unit, amount, plussign, separators)); QString str(formatWithUnit(unit, amount, plussign, separators));
str.replace(QChar(THIN_SP_CP), QString(THIN_SP_HTML)); str.replace(QChar(THIN_SP_CP), QString(THIN_SP_HTML));
return QString("<span style='white-space: nowrap;'>%1</span>").arg(str); return QString("<span style='white-space: nowrap;'>%1</span>").arg(str);
} }
QString BitcoinUnits::formatWithPrivacy(int unit, const CAmount& amount, SeparatorStyle separators, bool privacy) QString BitcoinUnits::formatWithPrivacy(Unit unit, const CAmount& amount, SeparatorStyle separators, bool privacy)
{ {
assert(amount >= 0); assert(amount >= 0);
QString value; QString value;
@@ -171,10 +152,11 @@ QString BitcoinUnits::formatWithPrivacy(int unit, const CAmount& amount, Separat
return value + QString(" ") + shortName(unit); return value + QString(" ") + shortName(unit);
} }
bool BitcoinUnits::parse(int unit, const QString &value, CAmount *val_out) bool BitcoinUnits::parse(Unit unit, const QString& value, CAmount* val_out)
{ {
if(!valid(unit) || value.isEmpty()) if (value.isEmpty()) {
return false; // Refuse to parse invalid unit or empty string return false; // Refuse to parse invalid unit or empty string
}
int num_decimals = decimals(unit); int num_decimals = decimals(unit);
// Ignore spaces and thin spaces when parsing // Ignore spaces and thin spaces when parsing
@@ -210,14 +192,9 @@ bool BitcoinUnits::parse(int unit, const QString &value, CAmount *val_out)
return ok; return ok;
} }
QString BitcoinUnits::getAmountColumnTitle(int unit) QString BitcoinUnits::getAmountColumnTitle(Unit unit)
{ {
QString amountTitle = QObject::tr("Amount"); return QObject::tr("Amount") + " (" + shortName(unit) + ")";
if (BitcoinUnits::valid(unit))
{
amountTitle += " ("+BitcoinUnits::shortName(unit) + ")";
}
return amountTitle;
} }
int BitcoinUnits::rowCount(const QModelIndex &parent) const int BitcoinUnits::rowCount(const QModelIndex &parent) const
@@ -240,7 +217,7 @@ QVariant BitcoinUnits::data(const QModelIndex &index, int role) const
case Qt::ToolTipRole: case Qt::ToolTipRole:
return QVariant(description(unit)); return QVariant(description(unit));
case UnitRole: case UnitRole:
return QVariant(static_cast<int>(unit)); return QVariant::fromValue(unit);
} }
} }
return QVariant(); return QVariant();
@@ -250,3 +227,40 @@ CAmount BitcoinUnits::maxMoney()
{ {
return MAX_MONEY; return MAX_MONEY;
} }
namespace {
qint8 ToQint8(BitcoinUnit unit)
{
switch (unit) {
case BitcoinUnit::BTC: return 0;
case BitcoinUnit::mBTC: return 1;
case BitcoinUnit::uBTC: return 2;
case BitcoinUnit::SAT: return 3;
} // no default case, so the compiler can warn about missing cases
assert(false);
}
BitcoinUnit FromQint8(qint8 num)
{
switch (num) {
case 0: return BitcoinUnit::BTC;
case 1: return BitcoinUnit::mBTC;
case 2: return BitcoinUnit::uBTC;
case 3: return BitcoinUnit::SAT;
}
assert(false);
}
} // namespace
QDataStream& operator<<(QDataStream& out, const BitcoinUnit& unit)
{
return out << ToQint8(unit);
}
QDataStream& operator>>(QDataStream& in, BitcoinUnit& unit)
{
qint8 input;
in >> input;
unit = FromQint8(input);
return in;
}
+18 -16
View File
@@ -8,6 +8,7 @@
#include <consensus/amount.h> #include <consensus/amount.h>
#include <QAbstractListModel> #include <QAbstractListModel>
#include <QDataStream>
#include <QString> #include <QString>
// U+2009 THIN SPACE = UTF-8 E2 80 89 // U+2009 THIN SPACE = UTF-8 E2 80 89
@@ -38,13 +39,13 @@ public:
/** Bitcoin units. /** Bitcoin units.
@note Source: https://en.bitcoin.it/wiki/Units . Please add only sensible ones @note Source: https://en.bitcoin.it/wiki/Units . Please add only sensible ones
*/ */
enum Unit enum class Unit {
{
BTC, BTC,
mBTC, mBTC,
uBTC, uBTC,
SAT SAT
}; };
Q_ENUM(Unit)
enum class SeparatorStyle enum class SeparatorStyle
{ {
@@ -59,30 +60,28 @@ public:
//! Get list of units, for drop-down box //! Get list of units, for drop-down box
static QList<Unit> availableUnits(); static QList<Unit> availableUnits();
//! Is unit ID valid?
static bool valid(int unit);
//! Long name //! Long name
static QString longName(int unit); static QString longName(Unit unit);
//! Short name //! Short name
static QString shortName(int unit); static QString shortName(Unit unit);
//! Longer description //! Longer description
static QString description(int unit); static QString description(Unit unit);
//! Number of Satoshis (1e-8) per unit //! Number of Satoshis (1e-8) per unit
static qint64 factor(int unit); static qint64 factor(Unit unit);
//! Number of decimals left //! Number of decimals left
static int decimals(int unit); static int decimals(Unit unit);
//! Format as string //! Format as string
static QString format(int unit, const CAmount& amount, bool plussign = false, SeparatorStyle separators = SeparatorStyle::STANDARD, bool justify = false); static QString format(Unit unit, const CAmount& amount, bool plussign = false, SeparatorStyle separators = SeparatorStyle::STANDARD, bool justify = false);
//! Format as string (with unit) //! Format as string (with unit)
static QString formatWithUnit(int unit, const CAmount& amount, bool plussign=false, SeparatorStyle separators=SeparatorStyle::STANDARD); static QString formatWithUnit(Unit unit, const CAmount& amount, bool plussign = false, SeparatorStyle separators = SeparatorStyle::STANDARD);
//! Format as HTML string (with unit) //! Format as HTML string (with unit)
static QString formatHtmlWithUnit(int unit, const CAmount& amount, bool plussign=false, SeparatorStyle separators=SeparatorStyle::STANDARD); static QString formatHtmlWithUnit(Unit unit, const CAmount& amount, bool plussign = false, SeparatorStyle separators = SeparatorStyle::STANDARD);
//! Format as string (with unit) of fixed length to preserve privacy, if it is set. //! Format as string (with unit) of fixed length to preserve privacy, if it is set.
static QString formatWithPrivacy(int unit, const CAmount& amount, SeparatorStyle separators, bool privacy); static QString formatWithPrivacy(Unit unit, const CAmount& amount, SeparatorStyle separators, bool privacy);
//! Parse string to coin amount //! Parse string to coin amount
static bool parse(int unit, const QString &value, CAmount *val_out); static bool parse(Unit unit, const QString& value, CAmount* val_out);
//! Gets title for amount column including current display unit if optionsModel reference available */ //! Gets title for amount column including current display unit if optionsModel reference available */
static QString getAmountColumnTitle(int unit); static QString getAmountColumnTitle(Unit unit);
///@} ///@}
//! @name AbstractListModel implementation //! @name AbstractListModel implementation
@@ -107,8 +106,11 @@ public:
static CAmount maxMoney(); static CAmount maxMoney();
private: private:
QList<BitcoinUnits::Unit> unitlist; QList<Unit> unitlist;
}; };
typedef BitcoinUnits::Unit BitcoinUnit; typedef BitcoinUnits::Unit BitcoinUnit;
QDataStream& operator<<(QDataStream& out, const BitcoinUnit& unit);
QDataStream& operator>>(QDataStream& in, BitcoinUnit& unit);
#endif // BITCOIN_QT_BITCOINUNITS_H #endif // BITCOIN_QT_BITCOINUNITS_H
+2 -2
View File
@@ -507,7 +507,7 @@ void CoinControlDialog::updateLabels(CCoinControl& m_coin_control, WalletModel *
} }
// actually update labels // actually update labels
int nDisplayUnit = BitcoinUnits::BTC; BitcoinUnit nDisplayUnit = BitcoinUnit::BTC;
if (model && model->getOptionsModel()) if (model && model->getOptionsModel())
nDisplayUnit = model->getOptionsModel()->getDisplayUnit(); nDisplayUnit = model->getOptionsModel()->getDisplayUnit();
@@ -590,7 +590,7 @@ void CoinControlDialog::updateView()
QFlags<Qt::ItemFlag> flgCheckbox = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable; QFlags<Qt::ItemFlag> flgCheckbox = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable;
QFlags<Qt::ItemFlag> flgTristate = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsAutoTristate; QFlags<Qt::ItemFlag> flgTristate = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsAutoTristate;
int nDisplayUnit = model->getOptionsModel()->getDisplayUnit(); BitcoinUnit nDisplayUnit = model->getOptionsModel()->getDisplayUnit();
for (const auto& coins : model->wallet().listCoins()) { for (const auto& coins : model->wallet().listCoins()) {
CCoinControlWidgetItem* itemWalletAddress{nullptr}; CCoinControlWidgetItem* itemWalletAddress{nullptr};
+2 -3
View File
@@ -178,8 +178,7 @@ bool parseBitcoinURI(const QUrl &uri, SendCoinsRecipient *out)
{ {
if(!i->second.isEmpty()) if(!i->second.isEmpty())
{ {
if(!BitcoinUnits::parse(BitcoinUnits::BTC, i->second, &rv.amount)) if (!BitcoinUnits::parse(BitcoinUnit::BTC, i->second, &rv.amount)) {
{
return false; return false;
} }
} }
@@ -211,7 +210,7 @@ QString formatBitcoinURI(const SendCoinsRecipient &info)
if (info.amount) if (info.amount)
{ {
ret += QString("?amount=%1").arg(BitcoinUnits::format(BitcoinUnits::BTC, info.amount, false, BitcoinUnits::SeparatorStyle::NEVER)); ret += QString("?amount=%1").arg(BitcoinUnits::format(BitcoinUnit::BTC, info.amount, false, BitcoinUnits::SeparatorStyle::NEVER));
paramCount++; paramCount++;
} }
+18 -13
View File
@@ -24,6 +24,7 @@
#include <QLatin1Char> #include <QLatin1Char>
#include <QSettings> #include <QSettings>
#include <QStringList> #include <QStringList>
#include <QVariant>
const char *DEFAULT_GUI_PROXY_HOST = "127.0.0.1"; const char *DEFAULT_GUI_PROXY_HOST = "127.0.0.1";
@@ -71,9 +72,16 @@ void OptionsModel::Init(bool resetSettings)
fMinimizeOnClose = settings.value("fMinimizeOnClose").toBool(); fMinimizeOnClose = settings.value("fMinimizeOnClose").toBool();
// Display // Display
if (!settings.contains("nDisplayUnit")) if (!settings.contains("DisplayBitcoinUnit")) {
settings.setValue("nDisplayUnit", BitcoinUnits::BTC); settings.setValue("DisplayBitcoinUnit", QVariant::fromValue(BitcoinUnit::BTC));
nDisplayUnit = settings.value("nDisplayUnit").toInt(); }
QVariant unit = settings.value("DisplayBitcoinUnit");
if (unit.canConvert<BitcoinUnit>()) {
m_display_bitcoin_unit = unit.value<BitcoinUnit>();
} else {
m_display_bitcoin_unit = BitcoinUnit::BTC;
settings.setValue("DisplayBitcoinUnit", QVariant::fromValue(m_display_bitcoin_unit));
}
if (!settings.contains("strThirdPartyTxUrls")) if (!settings.contains("strThirdPartyTxUrls"))
settings.setValue("strThirdPartyTxUrls", ""); settings.setValue("strThirdPartyTxUrls", "");
@@ -376,7 +384,7 @@ QVariant OptionsModel::data(const QModelIndex & index, int role) const
return m_sub_fee_from_amount; return m_sub_fee_from_amount;
#endif #endif
case DisplayUnit: case DisplayUnit:
return nDisplayUnit; return QVariant::fromValue(m_display_bitcoin_unit);
case ThirdPartyTxUrls: case ThirdPartyTxUrls:
return strThirdPartyTxUrls; return strThirdPartyTxUrls;
case Language: case Language:
@@ -584,16 +592,13 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in
return successful; return successful;
} }
/** Updates current unit in memory, settings and emits displayUnitChanged(newUnit) signal */ void OptionsModel::setDisplayUnit(const QVariant& new_unit)
void OptionsModel::setDisplayUnit(const QVariant &value)
{ {
if (!value.isNull()) if (new_unit.isNull() || new_unit.value<BitcoinUnit>() == m_display_bitcoin_unit) return;
{ m_display_bitcoin_unit = new_unit.value<BitcoinUnit>();
QSettings settings; QSettings settings;
nDisplayUnit = value.toInt(); settings.setValue("DisplayBitcoinUnit", QVariant::fromValue(m_display_bitcoin_unit));
settings.setValue("nDisplayUnit", nDisplayUnit); Q_EMIT displayUnitChanged(m_display_bitcoin_unit);
Q_EMIT displayUnitChanged(nDisplayUnit);
}
} }
void OptionsModel::setRestartRequired(bool fRequired) void OptionsModel::setRestartRequired(bool fRequired)
+7 -6
View File
@@ -6,6 +6,7 @@
#define BITCOIN_QT_OPTIONSMODEL_H #define BITCOIN_QT_OPTIONSMODEL_H
#include <cstdint> #include <cstdint>
#include <qt/bitcoinunits.h>
#include <qt/guiconstants.h> #include <qt/guiconstants.h>
#include <QAbstractListModel> #include <QAbstractListModel>
@@ -55,7 +56,7 @@ public:
ProxyUseTor, // bool ProxyUseTor, // bool
ProxyIPTor, // QString ProxyIPTor, // QString
ProxyPortTor, // int ProxyPortTor, // int
DisplayUnit, // BitcoinUnits::Unit DisplayUnit, // BitcoinUnit
ThirdPartyTxUrls, // QString ThirdPartyTxUrls, // QString
Language, // QString Language, // QString
UseEmbeddedMonospacedFont, // bool UseEmbeddedMonospacedFont, // bool
@@ -79,14 +80,14 @@ public:
int rowCount(const QModelIndex & parent = QModelIndex()) const override; int rowCount(const QModelIndex & parent = QModelIndex()) const override;
QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override; QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override;
bool setData(const QModelIndex & index, const QVariant & value, int role = Qt::EditRole) override; bool setData(const QModelIndex & index, const QVariant & value, int role = Qt::EditRole) override;
/** Updates current unit in memory, settings and emits displayUnitChanged(newUnit) signal */ /** Updates current unit in memory, settings and emits displayUnitChanged(new_unit) signal */
void setDisplayUnit(const QVariant &value); void setDisplayUnit(const QVariant& new_unit);
/* Explicit getters */ /* Explicit getters */
bool getShowTrayIcon() const { return m_show_tray_icon; } bool getShowTrayIcon() const { return m_show_tray_icon; }
bool getMinimizeToTray() const { return fMinimizeToTray; } bool getMinimizeToTray() const { return fMinimizeToTray; }
bool getMinimizeOnClose() const { return fMinimizeOnClose; } bool getMinimizeOnClose() const { return fMinimizeOnClose; }
int getDisplayUnit() const { return nDisplayUnit; } BitcoinUnit getDisplayUnit() const { return m_display_bitcoin_unit; }
QString getThirdPartyTxUrls() const { return strThirdPartyTxUrls; } QString getThirdPartyTxUrls() const { return strThirdPartyTxUrls; }
bool getUseEmbeddedMonospacedFont() const { return m_use_embedded_monospaced_font; } bool getUseEmbeddedMonospacedFont() const { return m_use_embedded_monospaced_font; }
bool getCoinControlFeatures() const { return fCoinControlFeatures; } bool getCoinControlFeatures() const { return fCoinControlFeatures; }
@@ -112,7 +113,7 @@ private:
bool fMinimizeToTray; bool fMinimizeToTray;
bool fMinimizeOnClose; bool fMinimizeOnClose;
QString language; QString language;
int nDisplayUnit; BitcoinUnit m_display_bitcoin_unit;
QString strThirdPartyTxUrls; QString strThirdPartyTxUrls;
bool m_use_embedded_monospaced_font; bool m_use_embedded_monospaced_font;
bool fCoinControlFeatures; bool fCoinControlFeatures;
@@ -127,7 +128,7 @@ private:
// Check settings version and upgrade default values if required // Check settings version and upgrade default values if required
void checkAndMigrate(); void checkAndMigrate();
Q_SIGNALS: Q_SIGNALS:
void displayUnitChanged(int unit); void displayUnitChanged(BitcoinUnit unit);
void coinControlFeaturesChanged(bool); void coinControlFeaturesChanged(bool);
void showTrayIconChanged(bool); void showTrayIconChanged(bool);
void useEmbeddedMonospacedFontChanged(bool); void useEmbeddedMonospacedFontChanged(bool);
+5 -5
View File
@@ -34,9 +34,9 @@ class TxViewDelegate : public QAbstractItemDelegate
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit TxViewDelegate(const PlatformStyle *_platformStyle, QObject *parent=nullptr): explicit TxViewDelegate(const PlatformStyle* _platformStyle, QObject* parent = nullptr)
QAbstractItemDelegate(parent), unit(BitcoinUnits::BTC), : QAbstractItemDelegate(parent), unit(BitcoinUnit::BTC),
platformStyle(_platformStyle) platformStyle(_platformStyle)
{ {
connect(this, &TxViewDelegate::width_changed, this, &TxViewDelegate::sizeHintChanged); connect(this, &TxViewDelegate::width_changed, this, &TxViewDelegate::sizeHintChanged);
} }
@@ -125,7 +125,7 @@ public:
return {DECORATION_SIZE + 8 + minimum_text_width, DECORATION_SIZE}; return {DECORATION_SIZE + 8 + minimum_text_width, DECORATION_SIZE};
} }
int unit; BitcoinUnit unit;
Q_SIGNALS: Q_SIGNALS:
//! An intermediate signal for emitting from the `paint() const` member function. //! An intermediate signal for emitting from the `paint() const` member function.
@@ -197,7 +197,7 @@ OverviewPage::~OverviewPage()
void OverviewPage::setBalance(const interfaces::WalletBalances& balances) void OverviewPage::setBalance(const interfaces::WalletBalances& balances)
{ {
int unit = walletModel->getOptionsModel()->getDisplayUnit(); BitcoinUnit unit = walletModel->getOptionsModel()->getDisplayUnit();
m_balances = balances; m_balances = balances;
if (walletModel->wallet().isLegacy()) { if (walletModel->wallet().isLegacy()) {
if (walletModel->wallet().privateKeysDisabled()) { if (walletModel->wallet().privateKeysDisabled()) {
+2 -2
View File
@@ -181,7 +181,7 @@ std::string PSBTOperationsDialog::renderTransaction(const PartiallySignedTransac
ExtractDestination(out.scriptPubKey, address); ExtractDestination(out.scriptPubKey, address);
totalAmount += out.nValue; totalAmount += out.nValue;
tx_description.append(tr(" * Sends %1 to %2") tx_description.append(tr(" * Sends %1 to %2")
.arg(BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, out.nValue)) .arg(BitcoinUnits::formatWithUnit(BitcoinUnit::BTC, out.nValue))
.arg(QString::fromStdString(EncodeDestination(address)))); .arg(QString::fromStdString(EncodeDestination(address))));
tx_description.append("<br>"); tx_description.append("<br>");
} }
@@ -193,7 +193,7 @@ std::string PSBTOperationsDialog::renderTransaction(const PartiallySignedTransac
tx_description.append(tr("Unable to calculate transaction fee or total transaction amount.")); tx_description.append(tr("Unable to calculate transaction fee or total transaction amount."));
} else { } else {
tx_description.append(tr("Pays transaction fee: ")); tx_description.append(tr("Pays transaction fee: "));
tx_description.append(BitcoinUnits::formatWithUnit(BitcoinUnits::BTC, *analysis.fee)); tx_description.append(BitcoinUnits::formatWithUnit(BitcoinUnit::BTC, *analysis.fee));
// add total amount in all subdivision units // add total amount in all subdivision units
tx_description.append("<hr />"); tx_description.append("<hr />");
+1 -2
View File
@@ -380,8 +380,7 @@ bool SendCoinsDialog::PrepareSendText(QString& question_string, QString& informa
question_string.append("<hr />"); question_string.append("<hr />");
CAmount totalAmount = m_current_transaction->getTotalTransactionAmount() + txFee; CAmount totalAmount = m_current_transaction->getTotalTransactionAmount() + txFee;
QStringList alternativeUnits; QStringList alternativeUnits;
for (const BitcoinUnits::Unit u : BitcoinUnits::availableUnits()) for (const BitcoinUnit 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));
} }
+8 -7
View File
@@ -7,24 +7,25 @@
#include <interfaces/chain.h> #include <interfaces/chain.h>
#include <interfaces/node.h> #include <interfaces/node.h>
#include <key_io.h>
#include <qt/bitcoinamountfield.h> #include <qt/bitcoinamountfield.h>
#include <qt/bitcoinunits.h>
#include <qt/clientmodel.h> #include <qt/clientmodel.h>
#include <qt/optionsmodel.h> #include <qt/optionsmodel.h>
#include <qt/overviewpage.h>
#include <qt/platformstyle.h> #include <qt/platformstyle.h>
#include <qt/qvalidatedlineedit.h> #include <qt/qvalidatedlineedit.h>
#include <qt/receivecoinsdialog.h>
#include <qt/receiverequestdialog.h>
#include <qt/recentrequeststablemodel.h>
#include <qt/sendcoinsdialog.h> #include <qt/sendcoinsdialog.h>
#include <qt/sendcoinsentry.h> #include <qt/sendcoinsentry.h>
#include <qt/transactiontablemodel.h> #include <qt/transactiontablemodel.h>
#include <qt/transactionview.h> #include <qt/transactionview.h>
#include <qt/walletmodel.h> #include <qt/walletmodel.h>
#include <key_io.h>
#include <test/util/setup_common.h> #include <test/util/setup_common.h>
#include <validation.h> #include <validation.h>
#include <wallet/wallet.h> #include <wallet/wallet.h>
#include <qt/overviewpage.h>
#include <qt/receivecoinsdialog.h>
#include <qt/recentrequeststablemodel.h>
#include <qt/receiverequestdialog.h>
#include <chrono> #include <chrono>
#include <memory> #include <memory>
@@ -196,7 +197,7 @@ void TestGUI(interfaces::Node& node)
// Check balance in send dialog // Check balance in send dialog
QLabel* balanceLabel = sendCoinsDialog.findChild<QLabel*>("labelBalance"); QLabel* balanceLabel = sendCoinsDialog.findChild<QLabel*>("labelBalance");
QString balanceText = balanceLabel->text(); QString balanceText = balanceLabel->text();
int unit = walletModel.getOptionsModel()->getDisplayUnit(); BitcoinUnit unit = walletModel.getOptionsModel()->getDisplayUnit();
CAmount balance = walletModel.wallet().getBalance(); CAmount balance = walletModel.wallet().getBalance();
QString balanceComparison = BitcoinUnits::formatWithUnit(unit, balance, false, BitcoinUnits::SeparatorStyle::ALWAYS); QString balanceComparison = BitcoinUnits::formatWithUnit(unit, balance, false, BitcoinUnits::SeparatorStyle::ALWAYS);
QCOMPARE(balanceText, balanceComparison); QCOMPARE(balanceText, balanceComparison);
@@ -222,7 +223,7 @@ void TestGUI(interfaces::Node& node)
overviewPage.setWalletModel(&walletModel); overviewPage.setWalletModel(&walletModel);
QLabel* balanceLabel = overviewPage.findChild<QLabel*>("labelBalance"); QLabel* balanceLabel = overviewPage.findChild<QLabel*>("labelBalance");
QString balanceText = balanceLabel->text().trimmed(); QString balanceText = balanceLabel->text().trimmed();
int unit = walletModel.getOptionsModel()->getDisplayUnit(); BitcoinUnit unit = walletModel.getOptionsModel()->getDisplayUnit();
CAmount balance = walletModel.wallet().getBalance(); CAmount balance = walletModel.wallet().getBalance();
QString balanceComparison = BitcoinUnits::formatWithUnit(unit, balance, false, BitcoinUnits::SeparatorStyle::ALWAYS); QString balanceComparison = BitcoinUnits::formatWithUnit(unit, balance, false, BitcoinUnits::SeparatorStyle::ALWAYS);
QCOMPARE(balanceText, balanceComparison); QCOMPARE(balanceText, balanceComparison);
+1 -1
View File
@@ -75,7 +75,7 @@ bool GetPaymentRequestMerchant(const std::string& pr, QString& merchant)
return false; return false;
} }
QString TransactionDesc::toHTML(interfaces::Node& node, interfaces::Wallet& wallet, TransactionRecord *rec, int unit) QString TransactionDesc::toHTML(interfaces::Node& node, interfaces::Wallet& wallet, TransactionRecord* rec, BitcoinUnit unit)
{ {
int numBlocks; int numBlocks;
interfaces::WalletTxStatus status; interfaces::WalletTxStatus status;
+3 -1
View File
@@ -5,6 +5,8 @@
#ifndef BITCOIN_QT_TRANSACTIONDESC_H #ifndef BITCOIN_QT_TRANSACTIONDESC_H
#define BITCOIN_QT_TRANSACTIONDESC_H #define BITCOIN_QT_TRANSACTIONDESC_H
#include <qt/bitcoinunits.h>
#include <QObject> #include <QObject>
#include <QString> #include <QString>
@@ -24,7 +26,7 @@ class TransactionDesc: public QObject
Q_OBJECT Q_OBJECT
public: public:
static QString toHTML(interfaces::Node& node, interfaces::Wallet& wallet, TransactionRecord *rec, int unit); static QString toHTML(interfaces::Node& node, interfaces::Wallet& wallet, TransactionRecord* rec, BitcoinUnit unit);
private: private:
TransactionDesc() {} TransactionDesc() {}
+2 -1
View File
@@ -5,6 +5,7 @@
#include <qt/transactiontablemodel.h> #include <qt/transactiontablemodel.h>
#include <qt/addresstablemodel.h> #include <qt/addresstablemodel.h>
#include <qt/bitcoinunits.h>
#include <qt/clientmodel.h> #include <qt/clientmodel.h>
#include <qt/guiconstants.h> #include <qt/guiconstants.h>
#include <qt/guiutil.h> #include <qt/guiutil.h>
@@ -232,7 +233,7 @@ public:
return nullptr; return nullptr;
} }
QString describe(interfaces::Node& node, interfaces::Wallet& wallet, TransactionRecord *rec, int unit) QString describe(interfaces::Node& node, interfaces::Wallet& wallet, TransactionRecord* rec, BitcoinUnit unit)
{ {
return TransactionDesc::toHTML(node, wallet, rec, unit); return TransactionDesc::toHTML(node, wallet, rec, unit);
} }
+2 -1
View File
@@ -6,6 +6,7 @@
#define BITCOIN_QT_WALLETVIEW_H #define BITCOIN_QT_WALLETVIEW_H
#include <consensus/amount.h> #include <consensus/amount.h>
#include <qt/bitcoinunits.h>
#include <QStackedWidget> #include <QStackedWidget>
@@ -115,7 +116,7 @@ Q_SIGNALS:
/** Encryption status of wallet changed */ /** Encryption status of wallet changed */
void encryptionStatusChanged(); void encryptionStatusChanged();
/** Notify that a new transaction appeared */ /** Notify that a new transaction appeared */
void incomingTransaction(const QString& date, int unit, const CAmount& amount, const QString& type, const QString& address, const QString& label, const QString& walletName); void incomingTransaction(const QString& date, BitcoinUnit unit, const CAmount& amount, const QString& type, const QString& address, const QString& label, const QString& walletName);
/** Notify that the out of sync warning icon has been pressed */ /** Notify that the out of sync warning icon has been pressed */
void outOfSyncWarningClicked(); void outOfSyncWarningClicked();
}; };