1 // Copyright (c) 2011-2017 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 #include <qt/bitcoinunits.h>
7 #include <primitives/transaction.h>
11 BitcoinUnits::BitcoinUnits(QObject
*parent
):
12 QAbstractListModel(parent
),
13 unitlist(availableUnits())
17 QList
<BitcoinUnits::Unit
> BitcoinUnits::availableUnits()
19 QList
<BitcoinUnits::Unit
> unitlist
;
21 unitlist
.append(mBTC
);
22 unitlist
.append(uBTC
);
26 bool BitcoinUnits::valid(int unit
)
39 QString
BitcoinUnits::longName(int unit
)
43 case BTC
: return QString("BTC");
44 case mBTC
: return QString("mBTC");
45 case uBTC
: return QString::fromUtf8("µBTC (bits)");
46 default: return QString("???");
50 QString
BitcoinUnits::shortName(int unit
)
54 case uBTC
: return QString::fromUtf8("bits");
55 default: return longName(unit
);
59 QString
BitcoinUnits::description(int unit
)
63 case BTC
: return QString("Bitcoins");
64 case mBTC
: return QString("Milli-Bitcoins (1 / 1" THIN_SP_UTF8
"000)");
65 case uBTC
: return QString("Micro-Bitcoins (bits) (1 / 1" THIN_SP_UTF8
"000" THIN_SP_UTF8
"000)");
66 default: return QString("???");
70 qint64
BitcoinUnits::factor(int unit
)
74 case BTC
: return 100000000;
75 case mBTC
: return 100000;
76 case uBTC
: return 100;
77 default: return 100000000;
81 int BitcoinUnits::decimals(int unit
)
92 QString
BitcoinUnits::format(int unit
, const CAmount
& nIn
, bool fPlus
, SeparatorStyle separators
)
94 // Note: not using straight sprintf here because we do NOT want
95 // localized number formatting.
97 return QString(); // Refuse to format invalid unit
98 qint64 n
= (qint64
)nIn
;
99 qint64 coin
= factor(unit
);
100 int num_decimals
= decimals(unit
);
101 qint64 n_abs
= (n
> 0 ? n
: -n
);
102 qint64 quotient
= n_abs
/ coin
;
103 qint64 remainder
= n_abs
% coin
;
104 QString quotient_str
= QString::number(quotient
);
105 QString remainder_str
= QString::number(remainder
).rightJustified(num_decimals
, '0');
107 // Use SI-style thin space separators as these are locale independent and can't be
108 // confused with the decimal marker.
109 QChar
thin_sp(THIN_SP_CP
);
110 int q_size
= quotient_str
.size();
111 if (separators
== separatorAlways
|| (separators
== separatorStandard
&& q_size
> 4))
112 for (int i
= 3; i
< q_size
; i
+= 3)
113 quotient_str
.insert(q_size
- i
, thin_sp
);
116 quotient_str
.insert(0, '-');
117 else if (fPlus
&& n
> 0)
118 quotient_str
.insert(0, '+');
119 return quotient_str
+ QString(".") + remainder_str
;
123 // NOTE: Using formatWithUnit in an HTML context risks wrapping
124 // quantities at the thousands separator. More subtly, it also results
125 // in a standard space rather than a thin space, due to a bug in Qt's
126 // XML whitespace canonicalisation
128 // Please take care to use formatHtmlWithUnit instead, when
131 QString
BitcoinUnits::formatWithUnit(int unit
, const CAmount
& amount
, bool plussign
, SeparatorStyle separators
)
133 return format(unit
, amount
, plussign
, separators
) + QString(" ") + shortName(unit
);
136 QString
BitcoinUnits::formatHtmlWithUnit(int unit
, const CAmount
& amount
, bool plussign
, SeparatorStyle separators
)
138 QString
str(formatWithUnit(unit
, amount
, plussign
, separators
));
139 str
.replace(QChar(THIN_SP_CP
), QString(THIN_SP_HTML
));
140 return QString("<span style='white-space: nowrap;'>%1</span>").arg(str
);
144 bool BitcoinUnits::parse(int unit
, const QString
&value
, CAmount
*val_out
)
146 if(!valid(unit
) || value
.isEmpty())
147 return false; // Refuse to parse invalid unit or empty string
148 int num_decimals
= decimals(unit
);
150 // Ignore spaces and thin spaces when parsing
151 QStringList parts
= removeSpaces(value
).split(".");
155 return false; // More than one dot
157 QString whole
= parts
[0];
164 if(decimals
.size() > num_decimals
)
166 return false; // Exceeds max precision
169 QString str
= whole
+ decimals
.leftJustified(num_decimals
, '0');
173 return false; // Longer numbers will exceed 63 bits
175 CAmount
retvalue(str
.toLongLong(&ok
));
183 QString
BitcoinUnits::getAmountColumnTitle(int unit
)
185 QString amountTitle
= QObject::tr("Amount");
186 if (BitcoinUnits::valid(unit
))
188 amountTitle
+= " ("+BitcoinUnits::shortName(unit
) + ")";
193 int BitcoinUnits::rowCount(const QModelIndex
&parent
) const
196 return unitlist
.size();
199 QVariant
BitcoinUnits::data(const QModelIndex
&index
, int role
) const
201 int row
= index
.row();
202 if(row
>= 0 && row
< unitlist
.size())
204 Unit unit
= unitlist
.at(row
);
208 case Qt::DisplayRole
:
209 return QVariant(longName(unit
));
210 case Qt::ToolTipRole
:
211 return QVariant(description(unit
));
213 return QVariant(static_cast<int>(unit
));
219 CAmount
BitcoinUnits::maxMoney()