mirror of
https://github.com/Retropex/bitcoin.git
synced 2025-05-12 19:20:42 +02:00
Merge 929 via tbc
This commit is contained in:
commit
fe176fa702
@ -159,6 +159,7 @@ BITCOIN_QT_H = \
|
||||
qt/sendcoinsrecipient.h \
|
||||
qt/signverifymessagedialog.h \
|
||||
qt/splashscreen.h \
|
||||
qt/tonalutils.h \
|
||||
qt/trafficgraphwidget.h \
|
||||
qt/transactiondesc.h \
|
||||
qt/transactiondescdialog.h \
|
||||
@ -254,6 +255,7 @@ BITCOIN_QT_BASE_CPP = \
|
||||
qt/qvaluecombobox.cpp \
|
||||
qt/rpcconsole.cpp \
|
||||
qt/splashscreen.cpp \
|
||||
qt/tonalutils.cpp \
|
||||
qt/trafficgraphwidget.cpp \
|
||||
qt/utilitydialog.cpp
|
||||
|
||||
|
@ -94,7 +94,11 @@ public:
|
||||
{
|
||||
bool valid = false;
|
||||
CAmount val = value(&valid);
|
||||
val = val + steps * singleStep;
|
||||
CAmount currentSingleStep = singleStep;
|
||||
if (!currentSingleStep) {
|
||||
currentSingleStep = BitcoinUnits::singlestep(currentUnit);
|
||||
}
|
||||
val = val + steps * currentSingleStep;
|
||||
val = qBound(m_min_amount, val, m_max_amount);
|
||||
setValue(val);
|
||||
}
|
||||
@ -151,7 +155,7 @@ public:
|
||||
|
||||
private:
|
||||
BitcoinUnit currentUnit{BitcoinUnit::BTC};
|
||||
CAmount singleStep{CAmount(100000)}; // satoshis
|
||||
CAmount singleStep{CAmount(0)};
|
||||
mutable QSize cachedMinimumSizeHint;
|
||||
bool m_allow_empty{true};
|
||||
CAmount m_min_amount{CAmount(0)};
|
||||
|
@ -3,6 +3,7 @@
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <qt/bitcoinunits.h>
|
||||
#include <qt/tonalutils.h>
|
||||
|
||||
#include <consensus/amount.h>
|
||||
|
||||
@ -11,6 +12,7 @@
|
||||
#include <cassert>
|
||||
|
||||
static constexpr auto MAX_DIGITS_BTC = 16;
|
||||
static constexpr auto MAX_DIGITS_TBC = 13;
|
||||
|
||||
BitcoinUnits::BitcoinUnits(QObject *parent):
|
||||
QAbstractListModel(parent),
|
||||
@ -25,6 +27,12 @@ QList<BitcoinUnit> BitcoinUnits::availableUnits()
|
||||
unitlist.append(Unit::mBTC);
|
||||
unitlist.append(Unit::uBTC);
|
||||
unitlist.append(Unit::SAT);
|
||||
if (TonalUtils::Supported())
|
||||
{
|
||||
unitlist.append(Unit::bTBC);
|
||||
unitlist.append(Unit::sTBC);
|
||||
unitlist.append(Unit::TBC);
|
||||
}
|
||||
return unitlist;
|
||||
}
|
||||
|
||||
@ -35,6 +43,9 @@ QString BitcoinUnits::longName(Unit unit)
|
||||
case Unit::mBTC: return QString("mBTC");
|
||||
case Unit::uBTC: return QString::fromUtf8("µBTC (bits)");
|
||||
case Unit::SAT: return QString("Satoshi (sat)");
|
||||
case Unit::bTBC: return QString::fromUtf8("ᵇTBC");
|
||||
case Unit::sTBC: return QString::fromUtf8("ˢTBC");
|
||||
case Unit::TBC: return QString("TBC");
|
||||
} // no default case, so the compiler can warn about missing cases
|
||||
assert(false);
|
||||
}
|
||||
@ -46,6 +57,9 @@ QString BitcoinUnits::shortName(Unit unit)
|
||||
case Unit::mBTC: return longName(unit);
|
||||
case Unit::uBTC: return QString("bits");
|
||||
case Unit::SAT: return QString("sat");
|
||||
case Unit::bTBC: return QString::fromUtf8("ᵇTBC");
|
||||
case Unit::sTBC: return QString::fromUtf8("ˢTBC");
|
||||
case Unit::TBC: return QString("TBC");
|
||||
} // no default case, so the compiler can warn about missing cases
|
||||
assert(false);
|
||||
}
|
||||
@ -53,10 +67,13 @@ QString BitcoinUnits::shortName(Unit unit)
|
||||
QString BitcoinUnits::description(Unit unit)
|
||||
{
|
||||
switch (unit) {
|
||||
case Unit::BTC: return QString("Bitcoins");
|
||||
case Unit::BTC: return QString("Bitcoins (decimal)");
|
||||
case Unit::mBTC: return QString("Milli-Bitcoins (1 / 1" THIN_SP_UTF8 "000)");
|
||||
case Unit::uBTC: return QString("Micro-Bitcoins (bits) (1 / 1" THIN_SP_UTF8 "000" THIN_SP_UTF8 "000)");
|
||||
case Unit::SAT: return QString("Satoshi (sat) (1 / 100" THIN_SP_UTF8 "000" THIN_SP_UTF8 "000)");
|
||||
case Unit::bTBC: return QString("Bong-Bitcoins (1,0000 tonal)");
|
||||
case Unit::sTBC: return QString("San-Bitcoins (100 tonal)");
|
||||
case Unit::TBC: return QString("Bitcoins (tonal)");
|
||||
} // no default case, so the compiler can warn about missing cases
|
||||
assert(false);
|
||||
}
|
||||
@ -68,6 +85,9 @@ qint64 BitcoinUnits::factor(Unit unit)
|
||||
case Unit::mBTC: return 100'000;
|
||||
case Unit::uBTC: return 100;
|
||||
case Unit::SAT: return 1;
|
||||
case Unit::bTBC: return 0x100000000LL;
|
||||
case Unit::sTBC: return 0x1000000;
|
||||
case Unit::TBC: return 0x10000;
|
||||
} // no default case, so the compiler can warn about missing cases
|
||||
assert(false);
|
||||
}
|
||||
@ -79,10 +99,57 @@ int BitcoinUnits::decimals(Unit unit)
|
||||
case Unit::mBTC: return 5;
|
||||
case Unit::uBTC: return 2;
|
||||
case Unit::SAT: return 0;
|
||||
case Unit::bTBC: return 8;
|
||||
case Unit::sTBC: return 6;
|
||||
case Unit::TBC: return 4;
|
||||
} // no default case, so the compiler can warn about missing cases
|
||||
assert(false);
|
||||
}
|
||||
|
||||
int BitcoinUnits::radix(Unit unit)
|
||||
{
|
||||
switch (unit) {
|
||||
case Unit::bTBC:
|
||||
case Unit::sTBC:
|
||||
case Unit::TBC:
|
||||
return 0x10;
|
||||
default:
|
||||
return 10;
|
||||
}
|
||||
}
|
||||
|
||||
BitcoinUnit BitcoinUnits::numsys(Unit unit)
|
||||
{
|
||||
switch (unit) {
|
||||
case Unit::bTBC:
|
||||
case Unit::sTBC:
|
||||
case Unit::TBC:
|
||||
return Unit::TBC;
|
||||
default:
|
||||
return Unit::BTC;
|
||||
}
|
||||
}
|
||||
|
||||
qint64 BitcoinUnits::max_digits(Unit unit)
|
||||
{
|
||||
switch (numsys(unit)) {
|
||||
case Unit::TBC:
|
||||
return MAX_DIGITS_TBC;
|
||||
default:
|
||||
return MAX_DIGITS_BTC;
|
||||
}
|
||||
}
|
||||
|
||||
qint64 BitcoinUnits::singlestep(Unit unit)
|
||||
{
|
||||
switch (numsys(unit)) {
|
||||
case Unit::TBC:
|
||||
return 0x10000;
|
||||
default:
|
||||
return 100000;
|
||||
}
|
||||
}
|
||||
|
||||
QString BitcoinUnits::format(Unit unit, const CAmount& nIn, bool fPlus, SeparatorStyle separators, bool justify)
|
||||
{
|
||||
// Note: not using straight sprintf here because we do NOT want
|
||||
@ -92,11 +159,22 @@ QString BitcoinUnits::format(Unit unit, const CAmount& nIn, bool fPlus, Separato
|
||||
int num_decimals = decimals(unit);
|
||||
qint64 n_abs = (n > 0 ? n : -n);
|
||||
qint64 quotient = n_abs / coin;
|
||||
QString quotient_str = QString::number(quotient);
|
||||
int uradix = radix(unit);
|
||||
QString quotient_str = QString::number(quotient, uradix);
|
||||
if (justify) {
|
||||
quotient_str = quotient_str.rightJustified(MAX_DIGITS_BTC - num_decimals, ' ');
|
||||
quotient_str = quotient_str.rightJustified(max_digits(unit) - num_decimals, ' ');
|
||||
}
|
||||
|
||||
QString remainder_str;
|
||||
if (num_decimals > 0) {
|
||||
const qint64 remainder = n_abs % coin;
|
||||
remainder_str = QString::number(remainder, uradix).rightJustified(num_decimals, '0');
|
||||
}
|
||||
|
||||
switch (numsys(unit)) {
|
||||
case Unit::BTC:
|
||||
{
|
||||
|
||||
// Use SI-style thin space separators as these are locale independent and can't be
|
||||
// confused with the decimal marker.
|
||||
QChar thin_sp(THIN_SP_CP);
|
||||
@ -105,18 +183,28 @@ QString BitcoinUnits::format(Unit unit, const CAmount& nIn, bool fPlus, Separato
|
||||
for (int i = 3; i < q_size; i += 3)
|
||||
quotient_str.insert(q_size - i, thin_sp);
|
||||
|
||||
break;
|
||||
}
|
||||
case Unit::TBC:
|
||||
{
|
||||
// Right-trim excess zeros after the decimal point
|
||||
static const QRegExp tail_zeros("0+$");
|
||||
remainder_str.remove(tail_zeros);
|
||||
TonalUtils::ConvertFromHex(quotient_str);
|
||||
TonalUtils::ConvertFromHex(remainder_str);
|
||||
break;
|
||||
}
|
||||
default: assert(false);
|
||||
}
|
||||
|
||||
if (n < 0)
|
||||
quotient_str.insert(0, '-');
|
||||
else if (fPlus && n > 0)
|
||||
quotient_str.insert(0, '+');
|
||||
|
||||
if (num_decimals > 0) {
|
||||
qint64 remainder = n_abs % coin;
|
||||
QString remainder_str = QString::number(remainder).rightJustified(num_decimals, '0');
|
||||
return quotient_str + QString(".") + remainder_str;
|
||||
} else {
|
||||
return quotient_str;
|
||||
}
|
||||
if (!remainder_str.isEmpty())
|
||||
quotient_str += QString(".") + remainder_str;
|
||||
return quotient_str;
|
||||
}
|
||||
|
||||
|
||||
@ -180,11 +268,18 @@ bool BitcoinUnits::parse(Unit unit, const QString& value, CAmount* val_out)
|
||||
bool ok = false;
|
||||
QString str = whole + decimals.leftJustified(num_decimals, '0');
|
||||
|
||||
Unit unumsys = numsys(unit);
|
||||
if (unumsys == Unit::TBC) {
|
||||
if (str.size() > 15)
|
||||
return false; // Longer numbers may exceed 63 bits
|
||||
TonalUtils::ConvertToHex(str);
|
||||
} else
|
||||
if(str.size() > 18)
|
||||
{
|
||||
return false; // Longer numbers will exceed 63 bits
|
||||
}
|
||||
CAmount retvalue(str.toLongLong(&ok));
|
||||
|
||||
CAmount retvalue(str.toLongLong(&ok, radix(unit)));
|
||||
if(val_out)
|
||||
{
|
||||
*val_out = retvalue;
|
||||
@ -228,18 +323,21 @@ CAmount BitcoinUnits::maxMoney()
|
||||
return MAX_MONEY;
|
||||
}
|
||||
|
||||
namespace {
|
||||
qint8 ToQint8(BitcoinUnit unit)
|
||||
std::variant<qint8, QString> BitcoinUnits::ToSetting(BitcoinUnit unit)
|
||||
{
|
||||
switch (unit) {
|
||||
case BitcoinUnit::BTC: return 0;
|
||||
case BitcoinUnit::mBTC: return 1;
|
||||
case BitcoinUnit::uBTC: return 2;
|
||||
case BitcoinUnit::SAT: return 3;
|
||||
case BitcoinUnit::BTC: return qint8{0};
|
||||
case BitcoinUnit::mBTC: return qint8{1};
|
||||
case BitcoinUnit::uBTC: return qint8{2};
|
||||
case BitcoinUnit::SAT: return qint8{3};
|
||||
case BitcoinUnit::bTBC: return QString("bTBC");
|
||||
case BitcoinUnit::sTBC: return QString("sTBC");
|
||||
case BitcoinUnit::TBC: return QString("TBC");
|
||||
} // no default case, so the compiler can warn about missing cases
|
||||
assert(false);
|
||||
}
|
||||
|
||||
namespace {
|
||||
BitcoinUnit FromQint8(qint8 num)
|
||||
{
|
||||
switch (num) {
|
||||
@ -248,13 +346,32 @@ BitcoinUnit FromQint8(qint8 num)
|
||||
case 2: return BitcoinUnit::uBTC;
|
||||
case 3: return BitcoinUnit::SAT;
|
||||
}
|
||||
assert(false);
|
||||
return BitcoinUnit::BTC;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
BitcoinUnit BitcoinUnits::FromSetting(const QString& s, BitcoinUnit def)
|
||||
{
|
||||
if (s == "0") return BitcoinUnit::BTC;
|
||||
if (s == "1") return BitcoinUnit::mBTC;
|
||||
if (s == "2") return BitcoinUnit::uBTC;
|
||||
if (s == "3") return BitcoinUnit::SAT;
|
||||
if (s == "4") return BitcoinUnit::sTBC;
|
||||
if (s == "5") return BitcoinUnit::TBC;
|
||||
if (s == "bTBC") return BitcoinUnit::bTBC;
|
||||
if (s == "sTBC") return BitcoinUnit::sTBC;
|
||||
if (s == "TBC") return BitcoinUnit::TBC;
|
||||
return def;
|
||||
}
|
||||
|
||||
QDataStream& operator<<(QDataStream& out, const BitcoinUnit& unit)
|
||||
{
|
||||
return out << ToQint8(unit);
|
||||
auto setting_val = BitcoinUnits::ToSetting(unit);
|
||||
if (const QString* setting_str = std::get_if<QString>(&setting_val)) {
|
||||
return out << qint8{0} << *setting_str;
|
||||
} else {
|
||||
return out << std::get<qint8>(setting_val);
|
||||
}
|
||||
}
|
||||
|
||||
QDataStream& operator>>(QDataStream& in, BitcoinUnit& unit)
|
||||
@ -262,5 +379,10 @@ QDataStream& operator>>(QDataStream& in, BitcoinUnit& unit)
|
||||
qint8 input;
|
||||
in >> input;
|
||||
unit = FromQint8(input);
|
||||
if (!in.atEnd()) {
|
||||
QString setting_str;
|
||||
in >> setting_str;
|
||||
unit = BitcoinUnits::FromSetting(setting_str, unit);
|
||||
}
|
||||
return in;
|
||||
}
|
||||
|
@ -43,7 +43,10 @@ public:
|
||||
BTC,
|
||||
mBTC,
|
||||
uBTC,
|
||||
SAT
|
||||
SAT,
|
||||
bTBC,
|
||||
sTBC,
|
||||
TBC,
|
||||
};
|
||||
Q_ENUM(Unit)
|
||||
|
||||
@ -60,6 +63,10 @@ public:
|
||||
|
||||
//! Get list of units, for drop-down box
|
||||
static QList<Unit> availableUnits();
|
||||
//! String for setting(s)
|
||||
static std::variant<qint8, QString> ToSetting(Unit unit);
|
||||
//! Convert setting(s) string to unit
|
||||
static Unit FromSetting(const QString&, Unit def);
|
||||
//! Long name
|
||||
static QString longName(Unit unit);
|
||||
//! Short name
|
||||
@ -68,8 +75,16 @@ public:
|
||||
static QString description(Unit unit);
|
||||
//! Number of Satoshis (1e-8) per unit
|
||||
static qint64 factor(Unit unit);
|
||||
//! Number of decimals left
|
||||
//! Number of fractional places
|
||||
static int decimals(Unit unit);
|
||||
//! Radix
|
||||
static int radix(Unit unit);
|
||||
//! Number system
|
||||
static Unit numsys(Unit unit);
|
||||
//! Number of digits total in maximum value
|
||||
static qint64 max_digits(Unit unit);
|
||||
//! "Single step" amount, in satoshis
|
||||
static qint64 singlestep(Unit unit);
|
||||
//! Format as string
|
||||
static QString format(Unit unit, const CAmount& amount, bool plussign = false, SeparatorStyle separators = SeparatorStyle::STANDARD, bool justify = false);
|
||||
//! Format as string (with unit)
|
||||
|
@ -245,9 +245,17 @@ bool OptionsModel::Init(bilingual_str& error)
|
||||
|
||||
// Display
|
||||
if (!settings.contains("DisplayBitcoinUnit")) {
|
||||
settings.setValue("DisplayBitcoinUnit", QVariant::fromValue(BitcoinUnit::BTC));
|
||||
auto init_unit = BitcoinUnit::BTC;
|
||||
if (settings.contains("nDisplayUnit")) {
|
||||
// Migrate to new setting
|
||||
init_unit = BitcoinUnits::FromSetting(settings.value("nDisplayUnit").toString(), init_unit);
|
||||
}
|
||||
settings.setValue("DisplayBitcoinUnit", QVariant::fromValue(init_unit));
|
||||
}
|
||||
QVariant unit = settings.value("DisplayBitcoinUnit");
|
||||
if (settings.contains("DisplayBitcoinUnitKnots")) {
|
||||
unit = settings.value("DisplayBitcoinUnitKnots");
|
||||
}
|
||||
if (unit.canConvert<BitcoinUnit>()) {
|
||||
m_display_bitcoin_unit = unit.value<BitcoinUnit>();
|
||||
} else {
|
||||
@ -919,7 +927,21 @@ void OptionsModel::setDisplayUnit(const QVariant& new_unit)
|
||||
if (new_unit.isNull() || new_unit.value<BitcoinUnit>() == m_display_bitcoin_unit) return;
|
||||
m_display_bitcoin_unit = new_unit.value<BitcoinUnit>();
|
||||
QSettings settings;
|
||||
settings.setValue("DisplayBitcoinUnit", QVariant::fromValue(m_display_bitcoin_unit));
|
||||
if (BitcoinUnits::numsys(m_display_bitcoin_unit) == BitcoinUnit::BTC) {
|
||||
settings.setValue("DisplayBitcoinUnit", QVariant::fromValue(m_display_bitcoin_unit));
|
||||
settings.remove("DisplayBitcoinUnitKnots");
|
||||
} else {
|
||||
settings.setValue("DisplayBitcoinUnitKnots", QVariant::fromValue(m_display_bitcoin_unit));
|
||||
}
|
||||
{
|
||||
// For older versions:
|
||||
auto setting_val = BitcoinUnits::ToSetting(m_display_bitcoin_unit);
|
||||
if (const QString* setting_str = std::get_if<QString>(&setting_val)) {
|
||||
settings.setValue("nDisplayUnit", *setting_str);
|
||||
} else {
|
||||
settings.setValue("nDisplayUnit", std::get<qint8>(setting_val));
|
||||
}
|
||||
}
|
||||
Q_EMIT displayUnitChanged(m_display_bitcoin_unit);
|
||||
}
|
||||
|
||||
|
83
src/qt/tonalutils.cpp
Normal file
83
src/qt/tonalutils.cpp
Normal file
@ -0,0 +1,83 @@
|
||||
// Copyright (c) 2016 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <qt/tonalutils.h>
|
||||
|
||||
#include <QFont>
|
||||
#include <QFontMetrics>
|
||||
#include <QRegExp>
|
||||
#include <QRegExpValidator>
|
||||
#include <QString>
|
||||
|
||||
static const QList<QChar> tonal_digits{0xe8ef, 0xe8ee, 0xe8ed, 0xe8ec, 0xe8eb, 0xe8ea, 0xe8e9, '8', '7', '6', '5', '4', '3', '2', '1', '0'};
|
||||
|
||||
namespace {
|
||||
|
||||
bool font_supports_tonal(const QFont& font)
|
||||
{
|
||||
const QFontMetrics fm(font);
|
||||
QString s = "000";
|
||||
const QSize sz = fm.size(0, s);
|
||||
for (const auto& c : tonal_digits) {
|
||||
if (!fm.inFont(c)) return false;
|
||||
s[0] = s[1] = s[2] = c;
|
||||
if (sz != fm.size(0, s)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // anon namespace
|
||||
|
||||
bool TonalUtils::Supported()
|
||||
{
|
||||
QFont default_font;
|
||||
if (font_supports_tonal(default_font)) return true;
|
||||
QFont last_resort_font(default_font.lastResortFamily());
|
||||
if (font_supports_tonal(last_resort_font)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
#define RE_TONAL_DIGIT "[\\d\\xe8e0-\\xe8ef\\xe9d0-\\xe9df]"
|
||||
static QRegExpValidator tv(QRegExp("-?(?:" RE_TONAL_DIGIT "+\\.?|" RE_TONAL_DIGIT "*\\." RE_TONAL_DIGIT "+)"), nullptr);
|
||||
|
||||
QValidator::State TonalUtils::validate(QString&input, int&pos)
|
||||
{
|
||||
return tv.validate(input, pos);
|
||||
}
|
||||
|
||||
void TonalUtils::ConvertFromHex(QString&str)
|
||||
{
|
||||
for (int i = 0; i < str.size(); ++i)
|
||||
{
|
||||
ushort c = str[i].unicode();
|
||||
if (c == '9')
|
||||
str[i] = 0xe8e9;
|
||||
else
|
||||
if (c >= 'A' && c <= 'F')
|
||||
str[i] = c + (0xe8ea - 'A');
|
||||
else
|
||||
if (c >= 'a' && c <= 'f')
|
||||
str[i] = c + (0xe8ea - 'a');
|
||||
}
|
||||
}
|
||||
|
||||
void TonalUtils::ConvertToHex(QString&str)
|
||||
{
|
||||
for (int i = 0; i < str.size(); ++i)
|
||||
{
|
||||
ushort c = str[i].unicode();
|
||||
if (c == '9')
|
||||
str[i] = 'a';
|
||||
else
|
||||
if (c >= 0xe8e0 && c <= 0xe8e9) { // UCSUR 0-9
|
||||
str[i] = c - (0xe8e0 - '0');
|
||||
} else if (c >= 0xe8ea && c <= 0xe8ef) { // UCSUR a-f
|
||||
str[i] = c - (0xe8ea - 'a');
|
||||
} else if (c >= 0xe9d0 && c <= 0xe9d9) {
|
||||
str[i] = c - (0xe9d0 - '0');
|
||||
} else
|
||||
if (c >= 0xe9da && c <= 0xe9df)
|
||||
str[i] = c - 0xe999;
|
||||
}
|
||||
}
|
25
src/qt/tonalutils.h
Normal file
25
src/qt/tonalutils.h
Normal file
@ -0,0 +1,25 @@
|
||||
// Copyright (c) 2016 The Bitcoin Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#ifndef BITCOIN_QT_TONALUTILS_H
|
||||
#define BITCOIN_QT_TONALUTILS_H
|
||||
|
||||
#include <QValidator>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QString;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
class TonalUtils
|
||||
{
|
||||
public:
|
||||
static bool Supported();
|
||||
|
||||
static QValidator::State validate(QString&input, int&pos);
|
||||
|
||||
static void ConvertFromHex(QString&);
|
||||
static void ConvertToHex(QString&);
|
||||
};
|
||||
|
||||
#endif // BITCOIN_QT_TONALUTILS_H
|
Loading…
Reference in New Issue
Block a user