limenkaunits.h raw
1 // Copyright (c) 2011-2021 The Limenka 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 LIMENKA_QT_LIMENKAUNITS_H
6 #define LIMENKA_QT_LIMENKAUNITS_H
7
8 #include <consensus/amount.h>
9
10 #include <QAbstractListModel>
11 #include <QDataStream>
12 #include <QFont>
13 #include <QString>
14
15 // U+2009 THIN SPACE = UTF-8 E2 80 89
16 #define REAL_THIN_SP_CP 0x2009
17 #define REAL_THIN_SP_UTF8 "\xE2\x80\x89"
18
19 // QMessageBox seems to have a bug whereby it doesn't display thin/hair spaces
20 // correctly. Workaround is to display a space in a small font. If you
21 // change this, please test that it doesn't cause the parent span to start
22 // wrapping.
23 #define HTML_HACK_SP "<span style='white-space: nowrap; font-size: 6pt'> </span>"
24
25 // Define THIN_SP_* variables to be our preferred type of thin space
26 #define THIN_SP_CP REAL_THIN_SP_CP
27 #define THIN_SP_UTF8 REAL_THIN_SP_UTF8
28 #define THIN_SP_HTML HTML_HACK_SP
29
30 /** Limenka ticker and symbol constants. */
31 static constexpr const char* TICKER = "LMKA";
32 static constexpr const char* SYMBOL_WHOLE = "\xce\xbb"; // λ (lambda)
33 static constexpr const char* SYMBOL_ATTO = "\xce\x9b"; // Λ (capital lambda)
34
35 /** Limenka unit definitions. Encapsulates parsing and formatting
36 and serves as list model for drop-down selection boxes.
37 */
38 class LimenkaUnits: public QAbstractListModel
39 {
40 Q_OBJECT
41
42 public:
43 explicit LimenkaUnits(QObject *parent);
44
45 /** Limenka units.
46 @note Source: https://en.limenka.it/wiki/Units . Please add only sensible ones
47 */
48 enum class Unit {
49 BTC, // λ whole units (1.23456789 λ)
50 mBTC, // millisats (legacy, deprecated)
51 uBTC, // microsats (legacy, deprecated)
52 SAT, // satoshis (integer)
53 ATTO, // attosats (Λ) - only available post-activation
54 bTBC, // legacy
55 sTBC, // legacy
56 TBC, // legacy
57 };
58 Q_ENUM(Unit)
59
60 /** Check if unit requires fork activation. */
61 static bool requiresActivation(Unit unit) { return unit == Unit::ATTO; }
62
63 enum class SeparatorStyle
64 {
65 NEVER,
66 STANDARD,
67 ALWAYS
68 };
69
70 //! @name Static API
71 //! Unit conversion and formatting
72 ///@{
73
74 //! Get list of units, for drop-down box
75 static QList<Unit> availableUnits();
76 //! String for setting(s)
77 static std::variant<qint8, QString> ToSetting(Unit unit);
78 //! Convert setting(s) string to unit
79 static Unit FromSetting(const QString&, Unit def);
80 //! Long name
81 static QString longName(Unit unit);
82 //! Short name
83 static QString shortName(Unit unit);
84 //! Longer description
85 static QString description(Unit unit);
86 //! Number of Satoshis (1e-8) per unit
87 static qint64 factor(Unit unit);
88 //! Number of fractional places
89 static int decimals(Unit unit);
90 //! Radix
91 static int radix(Unit unit);
92 //! Number system
93 static Unit numsys(Unit unit);
94 //! Number of digits total in maximum value
95 static qint64 max_digits(Unit unit);
96 //! "Single step" amount, in satoshis
97 static qint64 singlestep(Unit unit);
98 //! Format as string
99 static QString format(Unit unit, const CAmount& amount, bool plussign = false, SeparatorStyle separators = SeparatorStyle::STANDARD, bool justify = false);
100 //! Format as string (with unit)
101 static QString formatWithUnit(Unit unit, const CAmount& amount, bool plussign = false, SeparatorStyle separators = SeparatorStyle::STANDARD);
102 //! Format as HTML string (with unit)
103 static QString formatHtmlWithUnit(const QFont& font, Unit unit, const CAmount& amount, bool plussign = false, SeparatorStyle separators = SeparatorStyle::STANDARD);
104 /** Format amount with sub-satoshi precision (dimmed trailing digits). */
105 static QString formatWithSubSatoshi(const QFont& font, Unit unit, const CAmount& amount, uint64_t subSatoshi = 0, bool plussign = false, SeparatorStyle separators = SeparatorStyle::STANDARD);
106 //! Format as string (with unit) of fixed length to preserve privacy, if it is set.
107 static QString formatWithPrivacy(Unit unit, const CAmount& amount, SeparatorStyle separators, bool privacy);
108 //! Parse string to coin amount
109 static bool parse(Unit unit, const QString& value, CAmount* val_out);
110 //! Gets title for amount column including current display unit if optionsModel reference available */
111 static QString getAmountColumnTitle(Unit unit);
112 ///@}
113
114 //! @name AbstractListModel implementation
115 //! List model for unit drop-down selection box.
116 ///@{
117 enum RoleIndex {
118 /** Unit identifier */
119 UnitRole = Qt::UserRole
120 };
121 int rowCount(const QModelIndex &parent) const override;
122 QVariant data(const QModelIndex &index, int role) const override;
123 ///@}
124
125 static QString removeSpaces(QString text)
126 {
127 text.remove(' ');
128 text.remove(QChar(THIN_SP_CP));
129 return text;
130 }
131
132 //! Return maximum number of base units (Satoshis)
133 static CAmount maxMoney();
134
135 private:
136 QList<Unit> unitlist;
137 };
138 typedef LimenkaUnits::Unit LimenkaUnit;
139
140 QDataStream& operator<<(QDataStream& out, const LimenkaUnit& unit);
141 QDataStream& operator>>(QDataStream& in, LimenkaUnit& unit);
142
143 #endif // LIMENKA_QT_LIMENKAUNITS_H
144