1 // Copyright (c) 2011-2016 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 "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::name(int unit
)
43 case BTC
: return QString("BTC");
44 case mBTC
: return QString("mBTC");
45 case uBTC
: return QString::fromUtf8("μBTC");
46 default: return QString("???");
50 QString
BitcoinUnits::description(int unit
)
54 case BTC
: return QString("Bitcoins");
55 case mBTC
: return QString("Milli-Bitcoins (1 / 1" THIN_SP_UTF8
"000)");
56 case uBTC
: return QString("Micro-Bitcoins (1 / 1" THIN_SP_UTF8
"000" THIN_SP_UTF8
"000)");
57 default: return QString("???");
61 qint64
BitcoinUnits::factor(int unit
)
65 case BTC
: return 100000000;
66 case mBTC
: return 100000;
67 case uBTC
: return 100;
68 default: return 100000000;
72 int BitcoinUnits::decimals(int unit
)
83 QString
BitcoinUnits::format(int unit
, const CAmount
& nIn
, bool fPlus
, SeparatorStyle separators
)
85 // Note: not using straight sprintf here because we do NOT want
86 // localized number formatting.
88 return QString(); // Refuse to format invalid unit
89 qint64 n
= (qint64
)nIn
;
90 qint64 coin
= factor(unit
);
91 int num_decimals
= decimals(unit
);
92 qint64 n_abs
= (n
> 0 ? n
: -n
);
93 qint64 quotient
= n_abs
/ coin
;
94 qint64 remainder
= n_abs
% coin
;
95 QString quotient_str
= QString::number(quotient
);
96 QString remainder_str
= QString::number(remainder
).rightJustified(num_decimals
, '0');
98 // Use SI-style thin space separators as these are locale independent and can't be
99 // confused with the decimal marker.
100 QChar
thin_sp(THIN_SP_CP
);
101 int q_size
= quotient_str
.size();
102 if (separators
== separatorAlways
|| (separators
== separatorStandard
&& q_size
> 4))
103 for (int i
= 3; i
< q_size
; i
+= 3)
104 quotient_str
.insert(q_size
- i
, thin_sp
);
107 quotient_str
.insert(0, '-');
108 else if (fPlus
&& n
> 0)
109 quotient_str
.insert(0, '+');
110 return quotient_str
+ QString(".") + remainder_str
;
114 // NOTE: Using formatWithUnit in an HTML context risks wrapping
115 // quantities at the thousands separator. More subtly, it also results
116 // in a standard space rather than a thin space, due to a bug in Qt's
117 // XML whitespace canonicalisation
119 // Please take care to use formatHtmlWithUnit instead, when
122 QString
BitcoinUnits::formatWithUnit(int unit
, const CAmount
& amount
, bool plussign
, SeparatorStyle separators
)
124 return format(unit
, amount
, plussign
, separators
) + QString(" ") + name(unit
);
127 QString
BitcoinUnits::formatHtmlWithUnit(int unit
, const CAmount
& amount
, bool plussign
, SeparatorStyle separators
)
129 QString
str(formatWithUnit(unit
, amount
, plussign
, separators
));
130 str
.replace(QChar(THIN_SP_CP
), QString(THIN_SP_HTML
));
131 return QString("<span style='white-space: nowrap;'>%1</span>").arg(str
);
135 bool BitcoinUnits::parse(int unit
, const QString
&value
, CAmount
*val_out
)
137 if(!valid(unit
) || value
.isEmpty())
138 return false; // Refuse to parse invalid unit or empty string
139 int num_decimals
= decimals(unit
);
141 // Ignore spaces and thin spaces when parsing
142 QStringList parts
= removeSpaces(value
).split(".");
146 return false; // More than one dot
148 QString whole
= parts
[0];
155 if(decimals
.size() > num_decimals
)
157 return false; // Exceeds max precision
160 QString str
= whole
+ decimals
.leftJustified(num_decimals
, '0');
164 return false; // Longer numbers will exceed 63 bits
166 CAmount
retvalue(str
.toLongLong(&ok
));
174 QString
BitcoinUnits::getAmountColumnTitle(int unit
)
176 QString amountTitle
= QObject::tr("Amount");
177 if (BitcoinUnits::valid(unit
))
179 amountTitle
+= " ("+BitcoinUnits::name(unit
) + ")";
184 int BitcoinUnits::rowCount(const QModelIndex
&parent
) const
187 return unitlist
.size();
190 QVariant
BitcoinUnits::data(const QModelIndex
&index
, int role
) const
192 int row
= index
.row();
193 if(row
>= 0 && row
< unitlist
.size())
195 Unit unit
= unitlist
.at(row
);
199 case Qt::DisplayRole
:
200 return QVariant(name(unit
));
201 case Qt::ToolTipRole
:
202 return QVariant(description(unit
));
204 return QVariant(static_cast<int>(unit
));
210 CAmount
BitcoinUnits::maxMoney()