1 // Copyright (c) 2011-2018 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.
4 
5 #ifndef BITCOIN_QT_BITCOINUNITS_H
6 #define BITCOIN_QT_BITCOINUNITS_H
7 
8 #include <amount.h>
9 
10 #include <QAbstractListModel>
11 #include <QString>
12 
13 // U+2009 THIN SPACE = UTF-8 E2 80 89
14 #define REAL_THIN_SP_CP 0x2009
15 #define REAL_THIN_SP_UTF8 "\xE2\x80\x89"
16 #define REAL_THIN_SP_HTML "&thinsp;"
17 
18 // U+200A HAIR SPACE = UTF-8 E2 80 8A
19 #define HAIR_SP_CP 0x200A
20 #define HAIR_SP_UTF8 "\xE2\x80\x8A"
21 #define HAIR_SP_HTML "&#8202;"
22 
23 // U+2006 SIX-PER-EM SPACE = UTF-8 E2 80 86
24 #define SIXPEREM_SP_CP 0x2006
25 #define SIXPEREM_SP_UTF8 "\xE2\x80\x86"
26 #define SIXPEREM_SP_HTML "&#8198;"
27 
28 // U+2007 FIGURE SPACE = UTF-8 E2 80 87
29 #define FIGURE_SP_CP 0x2007
30 #define FIGURE_SP_UTF8 "\xE2\x80\x87"
31 #define FIGURE_SP_HTML "&#8199;"
32 
33 // QMessageBox seems to have a bug whereby it doesn't display thin/hair spaces
34 // correctly.  Workaround is to display a space in a small font.  If you
35 // change this, please test that it doesn't cause the parent span to start
36 // wrapping.
37 #define HTML_HACK_SP "<span style='white-space: nowrap; font-size: 6pt'> </span>"
38 
39 // Define THIN_SP_* variables to be our preferred type of thin space
40 #define THIN_SP_CP   REAL_THIN_SP_CP
41 #define THIN_SP_UTF8 REAL_THIN_SP_UTF8
42 #define THIN_SP_HTML HTML_HACK_SP
43 
44 /** Bitcoin unit definitions. Encapsulates parsing and formatting
45    and serves as list model for drop-down selection boxes.
46 */
47 class BitcoinUnits: public QAbstractListModel
48 {
49     Q_OBJECT
50 
51 public:
52     explicit BitcoinUnits(QObject *parent);
53 
54     /** Bitcoin units.
55       @note Source: https://en.bitcoin.it/wiki/Units . Please add only sensible ones
56      */
57     enum Unit
58     {
59         BTC,
60         mBTC,
61         uBTC,
62         SAT
63     };
64 
65     enum SeparatorStyle
66     {
67         separatorNever,
68         separatorStandard,
69         separatorAlways
70     };
71 
72     //! @name Static API
73     //! Unit conversion and formatting
74     ///@{
75 
76     //! Get list of units, for drop-down box
77     static QList<Unit> availableUnits();
78     //! Is unit ID valid?
79     static bool valid(int unit);
80     //! Long name
81     static QString longName(int unit);
82     //! Short name
83     static QString shortName(int unit);
84     //! Longer description
85     static QString description(int unit);
86     //! Number of Satoshis (1e-8) per unit
87     static qint64 factor(int unit);
88     //! Number of decimals left
89     static int decimals(int unit);
90     //! Format as string
91     static QString format(int unit, const CAmount& amount, bool plussign=false, SeparatorStyle separators=separatorStandard);
92     //! Format as string (with unit)
93     static QString formatWithUnit(int unit, const CAmount& amount, bool plussign=false, SeparatorStyle separators=separatorStandard);
94     //! Format as HTML string (with unit)
95     static QString formatHtmlWithUnit(int unit, const CAmount& amount, bool plussign=false, SeparatorStyle separators=separatorStandard);
96     //! Parse string to coin amount
97     static bool parse(int unit, const QString &value, CAmount *val_out);
98     //! Gets title for amount column including current display unit if optionsModel reference available */
99     static QString getAmountColumnTitle(int unit);
100     ///@}
101 
102     //! @name AbstractListModel implementation
103     //! List model for unit drop-down selection box.
104     ///@{
105     enum RoleIndex {
106         /** Unit identifier */
107         UnitRole = Qt::UserRole
108     };
109     int rowCount(const QModelIndex &parent) const;
110     QVariant data(const QModelIndex &index, int role) const;
111     ///@}
112 
removeSpaces(QString text)113     static QString removeSpaces(QString text)
114     {
115         text.remove(' ');
116         text.remove(QChar(THIN_SP_CP));
117 #if (THIN_SP_CP != REAL_THIN_SP_CP)
118         text.remove(QChar(REAL_THIN_SP_CP));
119 #endif
120         return text;
121     }
122 
123     //! Return maximum number of base units (Satoshis)
124     static CAmount maxMoney();
125 
126 private:
127     QList<BitcoinUnits::Unit> unitlist;
128 };
129 typedef BitcoinUnits::Unit BitcoinUnit;
130 
131 #endif // BITCOIN_QT_BITCOINUNITS_H
132