Raven Core  3.0.0
P2P Digital Currency
ravenunits.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2016 The Bitcoin Core developers
2 // Copyright (c) 2017-2019 The Raven Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 #include "ravenunits.h"
7 
9 
10 #include <QStringList>
11 
12 RavenUnits::RavenUnits(QObject *parent):
13  QAbstractListModel(parent),
14  unitlist(availableUnits())
15 {
16 }
17 
18 QList<RavenUnits::Unit> RavenUnits::availableUnits()
19 {
20  QList<RavenUnits::Unit> unitlist;
21  unitlist.append(RVN);
22  unitlist.append(mRVN);
23  unitlist.append(uRVN);
24  return unitlist;
25 }
26 
27 bool RavenUnits::valid(int unit)
28 {
29  switch(unit)
30  {
31  case RVN:
32  case mRVN:
33  case uRVN:
34  return true;
35  default:
36  return false;
37  }
38 }
39 
40 QString RavenUnits::name(int unit)
41 {
42  switch(unit)
43  {
44  case RVN: return QString("RVN");
45  case mRVN: return QString("mRVN");
46  case uRVN: return QString::fromUtf8("μRVN");
47  default: return QString("???");
48  }
49 }
50 
51 QString RavenUnits::description(int unit)
52 {
53  switch(unit)
54  {
55  case RVN: return QString("Ravens");
56  case mRVN: return QString("Milli-Ravens (1 / 1" THIN_SP_UTF8 "000)");
57  case uRVN: return QString("Micro-Ravens (1 / 1" THIN_SP_UTF8 "000" THIN_SP_UTF8 "000)");
58  default: return QString("???");
59  }
60 }
61 
62 qint64 RavenUnits::factor(int unit)
63 {
64  switch(unit)
65  {
66  case RVN: return 100000000;
67  case mRVN: return 100000;
68  case uRVN: return 100;
69  default: return 100000000;
70  }
71 }
72 
73 qint64 RavenUnits::factorAsset(int unit)
74 {
75  switch(unit)
76  {
77  case 0: return 1;
78  case 1: return 10;
79  case 2: return 100;
80  case 3: return 1000;
81  case 4: return 10000;
82  case 5: return 100000;
83  case 6: return 1000000;
84  case 7: return 10000000;
85  case 8: return 100000000;
86  default: return 100000000;
87  }
88 }
89 
90 int RavenUnits::decimals(int unit)
91 {
92  switch(unit)
93  {
94  case RVN: return 8;
95  case mRVN: return 5;
96  case uRVN: return 2;
97  default: return 0;
98  }
99 }
100 
101 QString RavenUnits::format(int unit, const CAmount& nIn, bool fPlus, SeparatorStyle separators, const int nAssetUnit)
102 {
103  // Note: not using straight sprintf here because we do NOT want
104  // localized number formatting.
105  if((nAssetUnit < 0 || nAssetUnit > 8) && !valid(unit))
106  return QString(); // Refuse to format invalid unit
107  qint64 n = (qint64)nIn;
108  qint64 coin = nAssetUnit >= 0 ? factorAsset(nAssetUnit) : factor(unit);
109  int num_decimals = nAssetUnit >= 0 ? nAssetUnit : decimals(unit);
110  qint64 n_abs = (n > 0 ? n : -n);
111  qint64 quotient = n_abs / coin;
112  qint64 remainder = n_abs % coin;
113  QString quotient_str = QString::number(quotient);
114  QString remainder_str = QString::number(remainder).rightJustified(num_decimals, '0');
115 
116  // Use SI-style thi
117  // n space separators as these are locale independent and can't be
118  // confused with the decimal marker.
119  QChar thin_sp(THIN_SP_CP);
120  int q_size = quotient_str.size();
121  if (separators == separatorAlways || (separators == separatorStandard && q_size > 4))
122  for (int i = 3; i < q_size; i += 3)
123  quotient_str.insert(q_size - i, thin_sp);
124 
125  if (n < 0)
126  quotient_str.insert(0, '-');
127  else if (fPlus && n > 0)
128  quotient_str.insert(0, '+');
129 
130  if (nAssetUnit == MIN_ASSET_UNITS)
131  return quotient_str;
132 
133 
134  return quotient_str + QString(".") + remainder_str;
135 }
136 
137 
138 // NOTE: Using formatWithUnit in an HTML context risks wrapping
139 // quantities at the thousands separator. More subtly, it also results
140 // in a standard space rather than a thin space, due to a bug in Qt's
141 // XML whitespace canonicalisation
142 //
143 // Please take care to use formatHtmlWithUnit instead, when
144 // appropriate.
145 
146 QString RavenUnits::formatWithUnit(int unit, const CAmount& amount, bool plussign, SeparatorStyle separators)
147 {
148  return format(unit, amount, plussign, separators) + QString(" ") + name(unit);
149 }
150 
151 QString RavenUnits::formatWithCustomName(QString customName, const CAmount& amount, int unit, bool plussign, SeparatorStyle separators)
152 {
153  return format(RVN, amount / factorAsset(MAX_ASSET_UNITS - unit), plussign, separators, unit) + QString(" ") + customName;
154 }
155 
156 QString RavenUnits::formatHtmlWithUnit(int unit, const CAmount& amount, bool plussign, SeparatorStyle separators)
157 {
158  QString str(formatWithUnit(unit, amount, plussign, separators));
159  str.replace(QChar(THIN_SP_CP), QString(THIN_SP_HTML));
160  return QString("<span style='white-space: nowrap;'>%1</span>").arg(str);
161 }
162 
163 
164 bool RavenUnits::parse(int unit, const QString &value, CAmount *val_out)
165 {
166  if(!valid(unit) || value.isEmpty())
167  return false; // Refuse to parse invalid unit or empty string
168  int num_decimals = decimals(unit);
169 
170  // Ignore spaces and thin spaces when parsing
171  QStringList parts = removeSpaces(value).split(".");
172 
173  if(parts.size() > 2)
174  {
175  return false; // More than one dot
176  }
177  QString whole = parts[0];
178  QString decimals;
179 
180  if(parts.size() > 1)
181  {
182  decimals = parts[1];
183  }
184  if(decimals.size() > num_decimals)
185  {
186  return false; // Exceeds max precision
187  }
188  bool ok = false;
189  QString str = whole + decimals.leftJustified(num_decimals, '0');
190 
191  if(str.size() > 18)
192  {
193  return false; // Longer numbers will exceed 63 bits
194  }
195  CAmount retvalue(str.toLongLong(&ok));
196  if(val_out)
197  {
198  *val_out = retvalue;
199  }
200  return ok;
201 }
202 
203 bool RavenUnits::assetParse(int assetUnit, const QString &value, CAmount *val_out)
204 {
205  if(!(assetUnit >= 0 && assetUnit <= 8) || value.isEmpty())
206  return false; // Refuse to parse invalid unit or empty string
207  int num_decimals = assetUnit;
208 
209  // Ignore spaces and thin spaces when parsing
210  QStringList parts = removeSpaces(value).split(".");
211 
212  if(parts.size() > 2)
213  {
214  return false; // More than one dot
215  }
216  QString whole = parts[0];
217  QString decimals;
218 
219  if(parts.size() > 1)
220  {
221  decimals = parts[1];
222  }
223  if(decimals.size() > num_decimals)
224  {
225  return false; // Exceeds max precision
226  }
227  bool ok = false;
228  QString str = whole + decimals.leftJustified(num_decimals, '0');
229 
230  if(str.size() > 18)
231  {
232  return false; // Longer numbers will exceed 63 bits
233  }
234  CAmount retvalue(str.toLongLong(&ok));
235  if(val_out)
236  {
237  *val_out = retvalue;
238  }
239  return ok;
240 }
241 
243 {
244  QString amountTitle = QObject::tr("Amount");
245  if (RavenUnits::valid(unit))
246  {
247  amountTitle += " ("+RavenUnits::name(unit) + ")";
248  }
249  return amountTitle;
250 }
251 
252 int RavenUnits::rowCount(const QModelIndex &parent) const
253 {
254  Q_UNUSED(parent);
255  return unitlist.size();
256 }
257 
258 QVariant RavenUnits::data(const QModelIndex &index, int role) const
259 {
260  int row = index.row();
261  if(row >= 0 && row < unitlist.size())
262  {
263  Unit unit = unitlist.at(row);
264  switch(role)
265  {
266  case Qt::EditRole:
267  case Qt::DisplayRole:
268  return QVariant(name(unit));
269  case Qt::ToolTipRole:
270  return QVariant(description(unit));
271  case UnitRole:
272  return QVariant(static_cast<int>(unit));
273  }
274  }
275  return QVariant();
276 }
277 
279 {
280  return MAX_MONEY;
281 }
static QString format(int unit, const CAmount &amount, bool plussign=false, SeparatorStyle separators=separatorStandard, const int nAssetUnit=MIN_ASSET_UNITS - 1)
Format as string.
Definition: ravenunits.cpp:101
static bool assetParse(int assetUnit, const QString &value, CAmount *val_out)
Definition: ravenunits.cpp:203
static bool valid(int unit)
Is unit ID valid?
Definition: ravenunits.cpp:27
static QString getAmountColumnTitle(int unit)
Gets title for amount column including current display unit if optionsModel reference available */...
Definition: ravenunits.cpp:242
#define THIN_SP_HTML
Definition: ravenunits.h:48
QList< RavenUnits::Unit > unitlist
Definition: ravenunits.h:135
static bool parse(int unit, const QString &value, CAmount *val_out)
Parse string to coin amount.
Definition: ravenunits.cpp:164
int64_t CAmount
Amount in corbies (Can be negative)
Definition: amount.h:13
static QString formatWithUnit(int unit, const CAmount &amount, bool plussign=false, SeparatorStyle separators=separatorStandard)
Format as string (with unit)
Definition: ravenunits.cpp:146
int rowCount(const QModelIndex &parent) const
Definition: ravenunits.cpp:252
static QString removeSpaces(QString text)
Definition: ravenunits.h:121
#define THIN_SP_UTF8
Definition: ravenunits.h:47
QVariant data(const QModelIndex &index, int role) const
Definition: ravenunits.cpp:258
RavenUnits(QObject *parent)
Definition: ravenunits.cpp:12
static qint64 factorAsset(int unit)
Number of Satoshis (1e-8) per unit for assets.
Definition: ravenunits.cpp:73
#define MIN_ASSET_UNITS
Definition: ravenunits.h:16
static QString formatHtmlWithUnit(int unit, const CAmount &amount, bool plussign=false, SeparatorStyle separators=separatorStandard)
Format as HTML string (with unit)
Definition: ravenunits.cpp:156
#define THIN_SP_CP
Definition: ravenunits.h:46
Unit identifier.
Definition: ravenunits.h:115
static QList< Unit > availableUnits()
Get list of units, for drop-down box.
Definition: ravenunits.cpp:18
static QString name(int unit)
Short name.
Definition: ravenunits.cpp:40
Unit
Raven units.
Definition: ravenunits.h:63
static QString formatWithCustomName(QString customName, const CAmount &amount, int unit=MAX_ASSET_UNITS, bool plussign=false, SeparatorStyle separators=separatorStandard)
Format as string (with custom name)
Definition: ravenunits.cpp:151
static int decimals(int unit)
Number of decimals left.
Definition: ravenunits.cpp:90
static qint64 factor(int unit)
Number of Satoshis (1e-8) per unit.
Definition: ravenunits.cpp:62
#define MAX_ASSET_UNITS
Definition: ravenunits.h:15
static CAmount maxMoney()
Return maximum number of base units (Satoshis)
Definition: ravenunits.cpp:278
static QString description(int unit)
Longer description.
Definition: ravenunits.cpp:51