LCOV - code coverage report
Current view: top level - src/qt - bitcoinunits.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 28 143 19.6 %
Date: 2020-09-26 01:30:44 Functions: 3 18 16.7 %

          Line data    Source code
       1             : // Copyright (c) 2011-2019 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             : #include <qt/bitcoinunits.h>
       6             : 
       7             : #include <QStringList>
       8             : 
       9             : #include <cassert>
      10             : 
      11           0 : BitcoinUnits::BitcoinUnits(QObject *parent):
      12           0 :         QAbstractListModel(parent),
      13           0 :         unitlist(availableUnits())
      14           0 : {
      15           0 : }
      16             : 
      17           0 : QList<BitcoinUnits::Unit> BitcoinUnits::availableUnits()
      18             : {
      19           0 :     QList<BitcoinUnits::Unit> unitlist;
      20           0 :     unitlist.append(BTC);
      21           0 :     unitlist.append(mBTC);
      22           0 :     unitlist.append(uBTC);
      23           0 :     unitlist.append(SAT);
      24             :     return unitlist;
      25           0 : }
      26             : 
      27           5 : bool BitcoinUnits::valid(int unit)
      28             : {
      29           5 :     switch(unit)
      30             :     {
      31             :     case BTC:
      32             :     case mBTC:
      33             :     case uBTC:
      34             :     case SAT:
      35           5 :         return true;
      36             :     default:
      37           0 :         return false;
      38             :     }
      39           5 : }
      40             : 
      41           0 : QString BitcoinUnits::longName(int unit)
      42             : {
      43           0 :     switch(unit)
      44             :     {
      45           0 :     case BTC: return QString("BTC");
      46           0 :     case mBTC: return QString("mBTC");
      47           0 :     case uBTC: return QString::fromUtf8("µBTC (bits)");
      48           0 :     case SAT: return QString("Satoshi (sat)");
      49           0 :     default: return QString("???");
      50             :     }
      51           0 : }
      52             : 
      53           0 : QString BitcoinUnits::shortName(int unit)
      54             : {
      55           0 :     switch(unit)
      56             :     {
      57           0 :     case uBTC: return QString::fromUtf8("bits");
      58           0 :     case SAT: return QString("sat");
      59           0 :     default: return longName(unit);
      60             :     }
      61           0 : }
      62             : 
      63           0 : QString BitcoinUnits::description(int unit)
      64             : {
      65           0 :     switch(unit)
      66             :     {
      67           0 :     case BTC: return QString("Bitcoins");
      68           0 :     case mBTC: return QString("Milli-Bitcoins (1 / 1" THIN_SP_UTF8 "000)");
      69           0 :     case uBTC: return QString("Micro-Bitcoins (bits) (1 / 1" THIN_SP_UTF8 "000" THIN_SP_UTF8 "000)");
      70           0 :     case SAT: return QString("Satoshi (sat) (1 / 100" THIN_SP_UTF8 "000" THIN_SP_UTF8 "000)");
      71           0 :     default: return QString("???");
      72             :     }
      73           0 : }
      74             : 
      75           0 : qint64 BitcoinUnits::factor(int unit)
      76             : {
      77           0 :     switch(unit)
      78             :     {
      79           0 :     case BTC: return 100000000;
      80           0 :     case mBTC: return 100000;
      81           0 :     case uBTC: return 100;
      82           0 :     case SAT: return 1;
      83           0 :     default: return 100000000;
      84             :     }
      85           0 : }
      86             : 
      87           5 : int BitcoinUnits::decimals(int unit)
      88             : {
      89           5 :     switch(unit)
      90             :     {
      91           5 :     case BTC: return 8;
      92           0 :     case mBTC: return 5;
      93           0 :     case uBTC: return 2;
      94           0 :     case SAT: return 0;
      95           0 :     default: return 0;
      96             :     }
      97           5 : }
      98             : 
      99           0 : QString BitcoinUnits::format(int unit, const CAmount& nIn, bool fPlus, SeparatorStyle separators, bool justify)
     100             : {
     101             :     // Note: not using straight sprintf here because we do NOT want
     102             :     // localized number formatting.
     103           0 :     if(!valid(unit))
     104           0 :         return QString(); // Refuse to format invalid unit
     105           0 :     qint64 n = (qint64)nIn;
     106           0 :     qint64 coin = factor(unit);
     107           0 :     int num_decimals = decimals(unit);
     108           0 :     qint64 n_abs = (n > 0 ? n : -n);
     109           0 :     qint64 quotient = n_abs / coin;
     110           0 :     QString quotient_str = QString::number(quotient);
     111           0 :     if (justify) quotient_str = quotient_str.rightJustified(16 - num_decimals, ' ');
     112             : 
     113             :     // Use SI-style thin space separators as these are locale independent and can't be
     114             :     // confused with the decimal marker.
     115           0 :     QChar thin_sp(THIN_SP_CP);
     116           0 :     int q_size = quotient_str.size();
     117           0 :     if (separators == SeparatorStyle::ALWAYS || (separators == SeparatorStyle::STANDARD && q_size > 4))
     118           0 :         for (int i = 3; i < q_size; i += 3)
     119           0 :             quotient_str.insert(q_size - i, thin_sp);
     120             : 
     121           0 :     if (n < 0)
     122           0 :         quotient_str.insert(0, '-');
     123           0 :     else if (fPlus && n > 0)
     124           0 :         quotient_str.insert(0, '+');
     125             : 
     126           0 :     if (num_decimals > 0) {
     127           0 :         qint64 remainder = n_abs % coin;
     128           0 :         QString remainder_str = QString::number(remainder).rightJustified(num_decimals, '0');
     129           0 :         return quotient_str + QString(".") + remainder_str;
     130           0 :     } else {
     131           0 :         return quotient_str;
     132             :     }
     133           0 : }
     134             : 
     135             : 
     136             : // NOTE: Using formatWithUnit in an HTML context risks wrapping
     137             : // quantities at the thousands separator. More subtly, it also results
     138             : // in a standard space rather than a thin space, due to a bug in Qt's
     139             : // XML whitespace canonicalisation
     140             : //
     141             : // Please take care to use formatHtmlWithUnit instead, when
     142             : // appropriate.
     143             : 
     144           0 : QString BitcoinUnits::formatWithUnit(int unit, const CAmount& amount, bool plussign, SeparatorStyle separators)
     145             : {
     146           0 :     return format(unit, amount, plussign, separators) + QString(" ") + shortName(unit);
     147           0 : }
     148             : 
     149           0 : QString BitcoinUnits::formatHtmlWithUnit(int unit, const CAmount& amount, bool plussign, SeparatorStyle separators)
     150             : {
     151           0 :     QString str(formatWithUnit(unit, amount, plussign, separators));
     152           0 :     str.replace(QChar(THIN_SP_CP), QString(THIN_SP_HTML));
     153           0 :     return QString("<span style='white-space: nowrap;'>%1</span>").arg(str);
     154           0 : }
     155             : 
     156           0 : QString BitcoinUnits::formatWithPrivacy(int unit, const CAmount& amount, SeparatorStyle separators, bool privacy)
     157             : {
     158           0 :     assert(amount >= 0);
     159           0 :     QString value;
     160           0 :     if (privacy) {
     161           0 :         value = format(unit, 0, false, separators, true).replace('0', '#');
     162           0 :     } else {
     163           0 :         value = format(unit, amount, false, separators, true);
     164             :     }
     165           0 :     return value + QString(" ") + shortName(unit);
     166           0 : }
     167             : 
     168           5 : bool BitcoinUnits::parse(int unit, const QString &value, CAmount *val_out)
     169             : {
     170           5 :     if(!valid(unit) || value.isEmpty())
     171           0 :         return false; // Refuse to parse invalid unit or empty string
     172           5 :     int num_decimals = decimals(unit);
     173             : 
     174             :     // Ignore spaces and thin spaces when parsing
     175           5 :     QStringList parts = removeSpaces(value).split(".");
     176             : 
     177           5 :     if(parts.size() > 2)
     178             :     {
     179           0 :         return false; // More than one dot
     180             :     }
     181           5 :     QString whole = parts[0];
     182           5 :     QString decimals;
     183             : 
     184           5 :     if(parts.size() > 1)
     185             :     {
     186           3 :         decimals = parts[1];
     187           3 :     }
     188           5 :     if(decimals.size() > num_decimals)
     189             :     {
     190           0 :         return false; // Exceeds max precision
     191             :     }
     192           5 :     bool ok = false;
     193           5 :     QString str = whole + decimals.leftJustified(num_decimals, '0');
     194             : 
     195           5 :     if(str.size() > 18)
     196             :     {
     197           0 :         return false; // Longer numbers will exceed 63 bits
     198             :     }
     199           5 :     CAmount retvalue(str.toLongLong(&ok));
     200           5 :     if(val_out)
     201             :     {
     202           5 :         *val_out = retvalue;
     203           5 :     }
     204           5 :     return ok;
     205           5 : }
     206             : 
     207           0 : QString BitcoinUnits::getAmountColumnTitle(int unit)
     208             : {
     209           0 :     QString amountTitle = QObject::tr("Amount");
     210           0 :     if (BitcoinUnits::valid(unit))
     211             :     {
     212           0 :         amountTitle += " ("+BitcoinUnits::shortName(unit) + ")";
     213           0 :     }
     214             :     return amountTitle;
     215           0 : }
     216             : 
     217           0 : int BitcoinUnits::rowCount(const QModelIndex &parent) const
     218             : {
     219             :     Q_UNUSED(parent);
     220           0 :     return unitlist.size();
     221             : }
     222             : 
     223           0 : QVariant BitcoinUnits::data(const QModelIndex &index, int role) const
     224             : {
     225           0 :     int row = index.row();
     226           0 :     if(row >= 0 && row < unitlist.size())
     227             :     {
     228           0 :         Unit unit = unitlist.at(row);
     229           0 :         switch(role)
     230             :         {
     231             :         case Qt::EditRole:
     232             :         case Qt::DisplayRole:
     233           0 :             return QVariant(longName(unit));
     234             :         case Qt::ToolTipRole:
     235           0 :             return QVariant(description(unit));
     236             :         case UnitRole:
     237           0 :             return QVariant(static_cast<int>(unit));
     238             :         }
     239           0 :     }
     240           0 :     return QVariant();
     241           0 : }
     242             : 
     243           0 : CAmount BitcoinUnits::maxMoney()
     244             : {
     245           0 :     return MAX_MONEY;
     246             : }

Generated by: LCOV version 1.15