wip
This commit is contained in:
@@ -24,16 +24,16 @@ void AddressCombo::setCurrentText(const QString& text) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddressCombo::addItem(const QString& text, double bal) {
|
void AddressCombo::addItem(const QString& text, CAmount bal) {
|
||||||
QString txt = AddressBook::addLabelToAddress(text);
|
QString txt = AddressBook::addLabelToAddress(text);
|
||||||
if (bal > 0)
|
if (bal.toqint64() > 0)
|
||||||
txt = txt % "(" % Settings::getZECDisplayFormat(bal) % ")";
|
txt = txt % "(" % bal.toDecimalZECString() % ")";
|
||||||
|
|
||||||
QComboBox::addItem(txt);
|
QComboBox::addItem(txt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddressCombo::insertItem(int index, const QString& text, double bal) {
|
void AddressCombo::insertItem(int index, const QString& text, CAmount bal) {
|
||||||
QString txt = AddressBook::addLabelToAddress(text) %
|
QString txt = AddressBook::addLabelToAddress(text) %
|
||||||
"(" % Settings::getZECDisplayFormat(bal) % ")";
|
"(" % bal.toDecimalZECString() % ")";
|
||||||
QComboBox::insertItem(index, txt);
|
QComboBox::insertItem(index, txt);
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
#ifndef ADDRESSCOMBO_H
|
#ifndef ADDRESSCOMBO_H
|
||||||
#define ADDRESSCOMBO_H
|
#define ADDRESSCOMBO_H
|
||||||
|
|
||||||
|
#include "camount.h"
|
||||||
#include "precompiled.h"
|
#include "precompiled.h"
|
||||||
|
|
||||||
class AddressCombo : public QComboBox
|
class AddressCombo : public QComboBox
|
||||||
@@ -12,8 +13,8 @@ public:
|
|||||||
QString itemText(int i);
|
QString itemText(int i);
|
||||||
QString currentText();
|
QString currentText();
|
||||||
|
|
||||||
void addItem(const QString& itemText, double bal);
|
void addItem(const QString& itemText, CAmount bal);
|
||||||
void insertItem(int index, const QString& text, double bal = 0.0);
|
void insertItem(int index, const QString& text, CAmount bal = CAmount::fromqint64(0));
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void setCurrentText(const QString& itemText);
|
void setCurrentText(const QString& itemText);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "balancestablemodel.h"
|
#include "balancestablemodel.h"
|
||||||
#include "addressbook.h"
|
#include "addressbook.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
#include "camount.h"
|
||||||
|
|
||||||
|
|
||||||
BalancesTableModel::BalancesTableModel(QObject *parent)
|
BalancesTableModel::BalancesTableModel(QObject *parent)
|
||||||
@@ -8,7 +9,7 @@ BalancesTableModel::BalancesTableModel(QObject *parent)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void BalancesTableModel::setNewData(const QList<QString> zaddrs, const QList<QString> taddrs,
|
void BalancesTableModel::setNewData(const QList<QString> zaddrs, const QList<QString> taddrs,
|
||||||
const QMap<QString, qint64> balances, const QList<UnspentOutput> outputs)
|
const QMap<QString, CAmount> balances, const QList<UnspentOutput> outputs)
|
||||||
{
|
{
|
||||||
loading = false;
|
loading = false;
|
||||||
|
|
||||||
@@ -22,7 +23,7 @@ void BalancesTableModel::setNewData(const QList<QString> zaddrs, const QList<QSt
|
|||||||
|
|
||||||
// Process the address balances into a list
|
// Process the address balances into a list
|
||||||
delete modeldata;
|
delete modeldata;
|
||||||
modeldata = new QList<std::tuple<QString, qint64>>();
|
modeldata = new QList<std::tuple<QString, CAmount>>();
|
||||||
std::for_each(balances.keyBegin(), balances.keyEnd(), [=] (auto keyIt) {
|
std::for_each(balances.keyBegin(), balances.keyEnd(), [=] (auto keyIt) {
|
||||||
modeldata->push_back(std::make_tuple(keyIt, balances.value(keyIt)));
|
modeldata->push_back(std::make_tuple(keyIt, balances.value(keyIt)));
|
||||||
});
|
});
|
||||||
@@ -30,13 +31,13 @@ void BalancesTableModel::setNewData(const QList<QString> zaddrs, const QList<QSt
|
|||||||
// Add all addresses that have no balances as well
|
// Add all addresses that have no balances as well
|
||||||
for (auto zaddr: zaddrs) {
|
for (auto zaddr: zaddrs) {
|
||||||
if (!balances.contains(zaddr)) {
|
if (!balances.contains(zaddr)) {
|
||||||
modeldata->push_back(std::make_tuple(zaddr, 0));
|
modeldata->push_back(std::make_tuple(zaddr, CAmount::fromqint64(0)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto taddr: taddrs) {
|
for (auto taddr: taddrs) {
|
||||||
if (!balances.contains(taddr)) {
|
if (!balances.contains(taddr)) {
|
||||||
modeldata->push_back(std::make_tuple(taddr, 0));
|
modeldata->push_back(std::make_tuple(taddr, CAmount::fromqint64(0)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,14 +102,14 @@ QVariant BalancesTableModel::data(const QModelIndex &index, int role) const
|
|||||||
if (role == Qt::DisplayRole) {
|
if (role == Qt::DisplayRole) {
|
||||||
switch (index.column()) {
|
switch (index.column()) {
|
||||||
case 0: return AddressBook::addLabelToAddress(std::get<0>(modeldata->at(index.row())));
|
case 0: return AddressBook::addLabelToAddress(std::get<0>(modeldata->at(index.row())));
|
||||||
case 1: return Settings::getZECDisplayFormat(std::get<1>(modeldata->at(index.row())));
|
case 1: return std::get<1>(modeldata->at(index.row())).toDecimalZECString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(role == Qt::ToolTipRole) {
|
if(role == Qt::ToolTipRole) {
|
||||||
switch (index.column()) {
|
switch (index.column()) {
|
||||||
case 0: return AddressBook::addLabelToAddress(std::get<0>(modeldata->at(index.row())));
|
case 0: return AddressBook::addLabelToAddress(std::get<0>(modeldata->at(index.row())));
|
||||||
case 1: return Settings::getUSDFromZecAmount(std::get<1>(modeldata->at(index.row())));
|
case 1: return std::get<1>(modeldata->at(index.row())).toDecimalZECString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "precompiled.h"
|
#include "precompiled.h"
|
||||||
#include "datamodel.h"
|
#include "datamodel.h"
|
||||||
|
#include "camount.h"
|
||||||
|
|
||||||
class BalancesTableModel : public QAbstractTableModel
|
class BalancesTableModel : public QAbstractTableModel
|
||||||
{
|
{
|
||||||
@@ -10,7 +11,7 @@ public:
|
|||||||
BalancesTableModel(QObject* parent);
|
BalancesTableModel(QObject* parent);
|
||||||
~BalancesTableModel();
|
~BalancesTableModel();
|
||||||
|
|
||||||
void setNewData(const QList<QString> zaddrs, const QList<QString> taddrs, const QMap<QString, qint64> balances, const QList<UnspentOutput> outputs);
|
void setNewData(const QList<QString> zaddrs, const QList<QString> taddrs, const QMap<QString, CAmount> balances, const QList<UnspentOutput> outputs);
|
||||||
|
|
||||||
int rowCount(const QModelIndex &parent) const;
|
int rowCount(const QModelIndex &parent) const;
|
||||||
int columnCount(const QModelIndex &parent) const;
|
int columnCount(const QModelIndex &parent) const;
|
||||||
@@ -18,7 +19,7 @@ public:
|
|||||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
|
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QList<std::tuple<QString, qint64>>* modeldata = nullptr;
|
QList<std::tuple<QString, CAmount>>* modeldata = nullptr;
|
||||||
QList<UnspentOutput>* unspentOutputs = nullptr;
|
QList<UnspentOutput>* unspentOutputs = nullptr;
|
||||||
|
|
||||||
bool loading = true;
|
bool loading = true;
|
||||||
|
|||||||
61
src/camount.cpp
Normal file
61
src/camount.cpp
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
#include "camount.h"
|
||||||
|
#include "settings.h"
|
||||||
|
|
||||||
|
#include "precompiled.h"
|
||||||
|
|
||||||
|
const int NUMPLACES = 8;
|
||||||
|
const qint64 COIN = 100000000;
|
||||||
|
|
||||||
|
double CAmount::toDecimalDouble() const {
|
||||||
|
return static_cast<double>(this->amount) / COIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString CAmount::toDecimalString() const {
|
||||||
|
if (amount < 0) {
|
||||||
|
CAmount negative(-1 * this->amount);
|
||||||
|
return "-" + negative.toDecimalString();
|
||||||
|
}
|
||||||
|
|
||||||
|
int wholePart = amount / COIN;
|
||||||
|
int decimalPart = amount % COIN;
|
||||||
|
|
||||||
|
QString r = QString::number(wholePart);
|
||||||
|
if (decimalPart > 0) {
|
||||||
|
QString decimalPartStr = QString::number(decimalPart);
|
||||||
|
QString leadingZeros = QString("0").repeated(NUMPLACES - decimalPartStr.length());
|
||||||
|
|
||||||
|
r = r + "." + leadingZeros + decimalPartStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString CAmount::toDecimalUSDString() const {
|
||||||
|
double dblAmount = static_cast<double>(this->amount) / COIN;
|
||||||
|
double price = Settings::getInstance()->getZECPrice();
|
||||||
|
|
||||||
|
return "$" + QLocale(QLocale::English).toString(dblAmount*price, 'f', 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString CAmount::toDecimalZECString() const {
|
||||||
|
return this->toDecimalString() % " " % Settings::getTokenName();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString CAmount::toDecimalZECUSDString() const {
|
||||||
|
auto usdString = this->toDecimalUSDString();
|
||||||
|
if (!usdString.isEmpty())
|
||||||
|
return this->toDecimalZECString() % " (" % usdString % ")";
|
||||||
|
else
|
||||||
|
return this->toDecimalZECString();
|
||||||
|
}
|
||||||
|
|
||||||
|
CAmount CAmount::fromDecimalString(QString decimalString) {
|
||||||
|
auto amtParts = decimalString.split(".");
|
||||||
|
qint64 r = amtParts[0].toULongLong() * COIN;
|
||||||
|
if (amtParts.length() == 2) {
|
||||||
|
auto trailingZeros = QString("0").repeated(NUMPLACES - amtParts[1].length());
|
||||||
|
r += QString(amtParts[1] + trailingZeros).toULongLong();
|
||||||
|
}
|
||||||
|
|
||||||
|
return CAmount(r);
|
||||||
|
}
|
||||||
47
src/camount.h
Normal file
47
src/camount.h
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
#ifndef CAMOUNT_H
|
||||||
|
#define CAMOUNT_H
|
||||||
|
|
||||||
|
|
||||||
|
class CAmount {
|
||||||
|
private:
|
||||||
|
CAmount(qint64 amount) {
|
||||||
|
this->amount = amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
qint64 amount;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static CAmount fromDecimalString(QString decimalString);
|
||||||
|
static CAmount fromqint64(qint64 a) {
|
||||||
|
return CAmount(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
CAmount() : amount(0) {};
|
||||||
|
CAmount(const CAmount&) = default;
|
||||||
|
~CAmount() = default;
|
||||||
|
|
||||||
|
double toDecimalDouble() const;
|
||||||
|
QString toDecimalString() const;
|
||||||
|
QString toDecimalUSDString() const;
|
||||||
|
QString toDecimalZECString() const;
|
||||||
|
QString toDecimalZECUSDString() const;
|
||||||
|
qint64 toqint64() const { return amount; };
|
||||||
|
|
||||||
|
CAmount operator+ (const CAmount& other) const {
|
||||||
|
return CAmount(this->amount + other.amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
CAmount operator- (const CAmount& other) const {
|
||||||
|
return CAmount(this->amount - other.amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator< (const CAmount& other) const {
|
||||||
|
return this->amount < other.amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator> (const CAmount& other) const {
|
||||||
|
return this->amount > other.amount;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CAMOUNT_H
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "addressbook.h"
|
#include "addressbook.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
#include "camount.h"
|
||||||
#include "websockets.h"
|
#include "websockets.h"
|
||||||
|
|
||||||
using json = nlohmann::json;
|
using json = nlohmann::json;
|
||||||
@@ -91,18 +92,12 @@ void Controller::fillTxJsonParams(json& allRecepients, Tx tx) {
|
|||||||
// Construct the JSON params
|
// Construct the JSON params
|
||||||
json rec = json::object();
|
json rec = json::object();
|
||||||
rec["address"] = toAddr.addr.toStdString();
|
rec["address"] = toAddr.addr.toStdString();
|
||||||
rec["amount"] = toAddr.amount;
|
rec["amount"] = toAddr.amount.toqint64();
|
||||||
if (Settings::isZAddress(toAddr.addr) && !toAddr.memo.trimmed().isEmpty())
|
if (Settings::isZAddress(toAddr.addr) && !toAddr.memo.trimmed().isEmpty())
|
||||||
rec["memo"] = toAddr.memo.toStdString();
|
rec["memo"] = toAddr.memo.toStdString();
|
||||||
|
|
||||||
allRecepients.push_back(rec);
|
allRecepients.push_back(rec);
|
||||||
}
|
}
|
||||||
|
|
||||||
// // Add fees if custom fees are allowed.
|
|
||||||
// if (Settings::getInstance()->getAllowCustomFees()) {
|
|
||||||
// params.push_back(1); // minconf
|
|
||||||
// params.push_back(tx.fee);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -115,7 +110,7 @@ void Controller::noConnection() {
|
|||||||
main->ui->statusBar->showMessage(QObject::tr("No Connection"), 1000);
|
main->ui->statusBar->showMessage(QObject::tr("No Connection"), 1000);
|
||||||
|
|
||||||
// Clear balances table.
|
// Clear balances table.
|
||||||
QMap<QString, qint64> emptyBalances;
|
QMap<QString, CAmount> emptyBalances;
|
||||||
QList<UnspentOutput> emptyOutputs;
|
QList<UnspentOutput> emptyOutputs;
|
||||||
QList<QString> emptyAddresses;
|
QList<QString> emptyAddresses;
|
||||||
balancesTableModel->setNewData(emptyAddresses, emptyAddresses, emptyBalances, emptyOutputs);
|
balancesTableModel->setNewData(emptyAddresses, emptyAddresses, emptyBalances, emptyOutputs);
|
||||||
@@ -254,20 +249,21 @@ void Controller::updateUI(bool anyUnconfirmed) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Function to process reply of the listunspent and z_listunspent API calls, used below.
|
// Function to process reply of the listunspent and z_listunspent API calls, used below.
|
||||||
void Controller::processUnspent(const json& reply, QMap<QString, qint64>* balancesMap, QList<UnspentOutput>* unspentOutputs) {
|
void Controller::processUnspent(const json& reply, QMap<QString, CAmount>* balancesMap, QList<UnspentOutput>* unspentOutputs) {
|
||||||
auto processFn = [=](const json& array) {
|
auto processFn = [=](const json& array) {
|
||||||
for (auto& it : array) {
|
for (auto& it : array) {
|
||||||
QString qsAddr = QString::fromStdString(it["address"]);
|
QString qsAddr = QString::fromStdString(it["address"]);
|
||||||
int block = it["created_in_block"].get<json::number_unsigned_t>();
|
int block = it["created_in_block"].get<json::number_unsigned_t>();
|
||||||
QString txid = QString::fromStdString(it["created_in_txid"]);
|
QString txid = QString::fromStdString(it["created_in_txid"]);
|
||||||
QString amount = Settings::getDecimalString(it["value"].get<json::number_unsigned_t>());
|
CAmount amount = CAmount::fromqint64(it["value"].get<json::number_unsigned_t>());
|
||||||
|
|
||||||
bool spendable = it["unconfirmed_spent"].is_null() && it["spent"].is_null(); // TODO: Wait for 4 confirmations
|
bool spendable = it["unconfirmed_spent"].is_null() && it["spent"].is_null(); // TODO: Wait for 4 confirmations
|
||||||
bool pending = !it["unconfirmed_spent"].is_null();
|
bool pending = !it["unconfirmed_spent"].is_null();
|
||||||
|
|
||||||
unspentOutputs->push_back(UnspentOutput{ qsAddr, txid, amount, block, spendable, pending });
|
unspentOutputs->push_back(UnspentOutput{ qsAddr, txid, amount, block, spendable, pending });
|
||||||
if (spendable) {
|
if (spendable) {
|
||||||
(*balancesMap)[qsAddr] = (*balancesMap)[qsAddr] + it["value"].get<json::number_unsigned_t>();
|
(*balancesMap)[qsAddr] = (*balancesMap)[qsAddr] +
|
||||||
|
CAmount::fromqint64(it["value"].get<json::number_unsigned_t>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -284,26 +280,26 @@ void Controller::refreshBalances() {
|
|||||||
|
|
||||||
// 1. Get the Balances
|
// 1. Get the Balances
|
||||||
zrpc->fetchBalance([=] (json reply) {
|
zrpc->fetchBalance([=] (json reply) {
|
||||||
auto balT = reply["tbalance"].get<json::number_unsigned_t>();
|
CAmount balT = CAmount::fromqint64(reply["tbalance"].get<json::number_unsigned_t>());
|
||||||
auto balZ = reply["zbalance"].get<json::number_unsigned_t>();
|
CAmount balZ = CAmount::fromqint64(reply["zbalance"].get<json::number_unsigned_t>());
|
||||||
auto balTotal = balT + balZ;
|
CAmount balTotal = balT + balZ;
|
||||||
|
|
||||||
AppDataModel::getInstance()->setBalances(balT, balZ);
|
AppDataModel::getInstance()->setBalances(balT, balZ);
|
||||||
|
|
||||||
ui->balSheilded ->setText(Settings::getZECDisplayFormat(balZ));
|
ui->balSheilded ->setText(balZ.toDecimalZECString());
|
||||||
ui->balTransparent->setText(Settings::getZECDisplayFormat(balT));
|
ui->balTransparent->setText(balT.toDecimalZECString());
|
||||||
ui->balTotal ->setText(Settings::getZECDisplayFormat(balTotal));
|
ui->balTotal ->setText(balTotal.toDecimalZECString());
|
||||||
|
|
||||||
|
auto price = Settings::getInstance()->getZECPrice();
|
||||||
ui->balSheilded ->setToolTip(Settings::getZECDisplayFormat(balZ));
|
ui->balSheilded ->setToolTip(balZ.toDecimalZECUSDString());
|
||||||
ui->balTransparent->setToolTip(Settings::getZECDisplayFormat(balT));
|
ui->balTransparent->setToolTip(balT.toDecimalZECUSDString());
|
||||||
ui->balTotal ->setToolTip(Settings::getZECDisplayFormat(balTotal));
|
ui->balTotal ->setToolTip(balTotal.toDecimalZECUSDString());
|
||||||
});
|
});
|
||||||
|
|
||||||
// 2. Get the UTXOs
|
// 2. Get the UTXOs
|
||||||
// First, create a new UTXO list. It will be replacing the existing list when everything is processed.
|
// First, create a new UTXO list. It will be replacing the existing list when everything is processed.
|
||||||
auto newUnspentOutputs = new QList<UnspentOutput>();
|
auto newUnspentOutputs = new QList<UnspentOutput>();
|
||||||
auto newBalances = new QMap<QString, qint64>();
|
auto newBalances = new QMap<QString, CAmount>();
|
||||||
|
|
||||||
// Call the Transparent and Z unspent APIs serially and then, once they're done, update the UI
|
// Call the Transparent and Z unspent APIs serially and then, once they're done, update the UI
|
||||||
zrpc->fetchUnspent([=] (json reply) {
|
zrpc->fetchUnspent([=] (json reply) {
|
||||||
@@ -334,7 +330,7 @@ void Controller::refreshTransactions() {
|
|||||||
|
|
||||||
for (auto& it : reply.get<json::array_t>()) {
|
for (auto& it : reply.get<json::array_t>()) {
|
||||||
QString address;
|
QString address;
|
||||||
qint64 total_amount = 0;
|
CAmount total_amount = CAmount::fromqint64(0);
|
||||||
QList<TransactionItemDetail> items;
|
QList<TransactionItemDetail> items;
|
||||||
|
|
||||||
// First, check if there's outgoing metadata
|
// First, check if there's outgoing metadata
|
||||||
@@ -342,7 +338,9 @@ void Controller::refreshTransactions() {
|
|||||||
|
|
||||||
for (auto o: it["outgoing_metadata"].get<json::array_t>()) {
|
for (auto o: it["outgoing_metadata"].get<json::array_t>()) {
|
||||||
QString address = QString::fromStdString(o["address"]);
|
QString address = QString::fromStdString(o["address"]);
|
||||||
qint64 amount = -1 * o["value"].get<json::number_unsigned_t>(); // Sent items are -ve
|
|
||||||
|
// Sent items are -ve
|
||||||
|
CAmount amount = CAmount::fromqint64(-1 * o["value"].get<json::number_unsigned_t>());
|
||||||
|
|
||||||
QString memo;
|
QString memo;
|
||||||
if (!o["memo"].is_null()) {
|
if (!o["memo"].is_null()) {
|
||||||
@@ -350,7 +348,7 @@ void Controller::refreshTransactions() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
items.push_back(TransactionItemDetail{address, amount, memo});
|
items.push_back(TransactionItemDetail{address, amount, memo});
|
||||||
total_amount += amount;
|
total_amount = total_amount + amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (items.length() == 1) {
|
if (items.length() == 1) {
|
||||||
@@ -374,7 +372,7 @@ void Controller::refreshTransactions() {
|
|||||||
|
|
||||||
items.push_back(TransactionItemDetail{
|
items.push_back(TransactionItemDetail{
|
||||||
address,
|
address,
|
||||||
it["amount"].get<json::number_integer_t>(),
|
CAmount::fromqint64(it["amount"].get<json::number_integer_t>()),
|
||||||
""
|
""
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "precompiled.h"
|
#include "precompiled.h"
|
||||||
|
|
||||||
|
#include "camount.h"
|
||||||
#include "datamodel.h"
|
#include "datamodel.h"
|
||||||
#include "balancestablemodel.h"
|
#include "balancestablemodel.h"
|
||||||
#include "txtablemodel.h"
|
#include "txtablemodel.h"
|
||||||
@@ -20,14 +21,6 @@ struct WatchedTx {
|
|||||||
std::function<void(QString, QString)> error;
|
std::function<void(QString, QString)> error;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MigrationStatus {
|
|
||||||
bool available; // Whether the underlying zcashd supports migration?
|
|
||||||
bool enabled;
|
|
||||||
QString saplingAddress;
|
|
||||||
double unmigrated;
|
|
||||||
double migrated;
|
|
||||||
QList<QString> txids;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Controller
|
class Controller
|
||||||
{
|
{
|
||||||
@@ -78,7 +71,7 @@ private:
|
|||||||
|
|
||||||
void refreshTransactions();
|
void refreshTransactions();
|
||||||
|
|
||||||
void processUnspent (const json& reply, QMap<QString, qint64>* newBalances, QList<UnspentOutput>* newUnspentOutputs);
|
void processUnspent (const json& reply, QMap<QString, CAmount>* newBalances, QList<UnspentOutput>* newUnspentOutputs);
|
||||||
void updateUI (bool anyUnconfirmed);
|
void updateUI (bool anyUnconfirmed);
|
||||||
|
|
||||||
void getInfoThenRefresh(bool force);
|
void getInfoThenRefresh(bool force);
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ DataModel::DataModel() {
|
|||||||
QWriteLocker locker(lock);
|
QWriteLocker locker(lock);
|
||||||
|
|
||||||
utxos = new QList<UnspentOutput>();
|
utxos = new QList<UnspentOutput>();
|
||||||
balances = new QMap<QString, qint64>();
|
balances = new QMap<QString, CAmount>();
|
||||||
usedAddresses = new QMap<QString, bool>();
|
usedAddresses = new QMap<QString, bool>();
|
||||||
zaddresses = new QList<QString>();
|
zaddresses = new QList<QString>();
|
||||||
taddresses = new QList<QString>();
|
taddresses = new QList<QString>();
|
||||||
@@ -44,7 +44,7 @@ void DataModel::replaceTaddresses(QList<QString>* newT) {
|
|||||||
taddresses = newT;
|
taddresses = newT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataModel::replaceBalances(QMap<QString, qint64>* newBalances) {
|
void DataModel::replaceBalances(QMap<QString, CAmount>* newBalances) {
|
||||||
QWriteLocker locker(lock);
|
QWriteLocker locker(lock);
|
||||||
Q_ASSERT(newBalances);
|
Q_ASSERT(newBalances);
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
#ifndef DATAMODEL_H
|
#ifndef DATAMODEL_H
|
||||||
#define DATAMODEL_H
|
#define DATAMODEL_H
|
||||||
|
|
||||||
|
#include "camount.h"
|
||||||
#include "precompiled.h"
|
#include "precompiled.h"
|
||||||
|
|
||||||
|
|
||||||
struct UnspentOutput {
|
struct UnspentOutput {
|
||||||
QString address;
|
QString address;
|
||||||
QString txid;
|
QString txid;
|
||||||
QString amount;
|
CAmount amount;
|
||||||
int blockCreated;
|
int blockCreated;
|
||||||
bool spendable;
|
bool spendable;
|
||||||
bool pending;
|
bool pending;
|
||||||
@@ -19,7 +20,7 @@ class DataModel {
|
|||||||
public:
|
public:
|
||||||
void replaceZaddresses(QList<QString>* newZ);
|
void replaceZaddresses(QList<QString>* newZ);
|
||||||
void replaceTaddresses(QList<QString>* newZ);
|
void replaceTaddresses(QList<QString>* newZ);
|
||||||
void replaceBalances(QMap<QString, qint64>* newBalances);
|
void replaceBalances(QMap<QString, CAmount>* newBalances);
|
||||||
void replaceUTXOs(QList<UnspentOutput>* utxos);
|
void replaceUTXOs(QList<UnspentOutput>* utxos);
|
||||||
|
|
||||||
void markAddressUsed(QString address);
|
void markAddressUsed(QString address);
|
||||||
@@ -30,7 +31,7 @@ public:
|
|||||||
const QList<QString> getAllZAddresses() { QReadLocker locker(lock); return *zaddresses; }
|
const QList<QString> getAllZAddresses() { QReadLocker locker(lock); return *zaddresses; }
|
||||||
const QList<QString> getAllTAddresses() { QReadLocker locker(lock); return *taddresses; }
|
const QList<QString> getAllTAddresses() { QReadLocker locker(lock); return *taddresses; }
|
||||||
const QList<UnspentOutput> getUTXOs() { QReadLocker locker(lock); return *utxos; }
|
const QList<UnspentOutput> getUTXOs() { QReadLocker locker(lock); return *utxos; }
|
||||||
const QMap<QString, qint64> getAllBalances() { QReadLocker locker(lock); return *balances; }
|
const QMap<QString, CAmount> getAllBalances() { QReadLocker locker(lock); return *balances; }
|
||||||
const QMap<QString, bool> getUsedAddresses() { QReadLocker locker(lock); return *usedAddresses; }
|
const QMap<QString, bool> getUsedAddresses() { QReadLocker locker(lock); return *usedAddresses; }
|
||||||
|
|
||||||
|
|
||||||
@@ -40,7 +41,7 @@ private:
|
|||||||
int latestBlock;
|
int latestBlock;
|
||||||
|
|
||||||
QList<UnspentOutput>* utxos = nullptr;
|
QList<UnspentOutput>* utxos = nullptr;
|
||||||
QMap<QString, qint64>* balances = nullptr;
|
QMap<QString, CAmount>* balances = nullptr;
|
||||||
QMap<QString, bool>* usedAddresses = nullptr;
|
QMap<QString, bool>* usedAddresses = nullptr;
|
||||||
QList<QString>* zaddresses = nullptr;
|
QList<QString>* zaddresses = nullptr;
|
||||||
QList<QString>* taddresses = nullptr;
|
QList<QString>* taddresses = nullptr;
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "precompiled.h"
|
#include "precompiled.h"
|
||||||
|
|
||||||
|
#include "camount.h"
|
||||||
#include "connection.h"
|
#include "connection.h"
|
||||||
|
|
||||||
using json = nlohmann::json;
|
using json = nlohmann::json;
|
||||||
@@ -11,7 +12,7 @@ using json = nlohmann::json;
|
|||||||
// into a struct with address, amount, memo
|
// into a struct with address, amount, memo
|
||||||
struct TransactionItemDetail {
|
struct TransactionItemDetail {
|
||||||
QString address;
|
QString address;
|
||||||
qint64 amount;
|
CAmount amount;
|
||||||
QString memo;
|
QString memo;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -438,7 +438,7 @@ void MainWindow::payZcashURI(QString uri, QString myAddr) {
|
|||||||
|
|
||||||
ui->Address1->setText(paymentInfo.addr);
|
ui->Address1->setText(paymentInfo.addr);
|
||||||
ui->Address1->setCursorPosition(0);
|
ui->Address1->setCursorPosition(0);
|
||||||
ui->Amount1->setText(Settings::getDecimalString(paymentInfo.amt.toDouble()));
|
ui->Amount1->setText(paymentInfo.amt);
|
||||||
ui->MemoTxt1->setText(paymentInfo.memo);
|
ui->MemoTxt1->setText(paymentInfo.memo);
|
||||||
|
|
||||||
// And switch to the send tab.
|
// And switch to the send tab.
|
||||||
@@ -982,7 +982,7 @@ void MainWindow::setupReceiveTab() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ui->rcvLabel->setText(label);
|
ui->rcvLabel->setText(label);
|
||||||
ui->rcvBal->setText(Settings::getZECUSDDisplayFormat(rpc->getModel()->getAllBalances().value(addr)));
|
ui->rcvBal->setText(rpc->getModel()->getAllBalances().value(addr).toDecimalZECUSDString());
|
||||||
ui->txtReceive->setPlainText(addr);
|
ui->txtReceive->setPlainText(addr);
|
||||||
ui->qrcodeDisplay->setQrcodeString(addr);
|
ui->qrcodeDisplay->setQrcodeString(addr);
|
||||||
if (rpc->getModel()->getUsedAddresses().value(addr, false)) {
|
if (rpc->getModel()->getUsedAddresses().value(addr, false)) {
|
||||||
@@ -1073,7 +1073,7 @@ void MainWindow::updateTAddrCombo(bool checked) {
|
|||||||
// If the address is in the address book, add it.
|
// If the address is in the address book, add it.
|
||||||
if (labels.contains(taddr) && !addrs.contains(taddr)) {
|
if (labels.contains(taddr) && !addrs.contains(taddr)) {
|
||||||
addrs.insert(taddr);
|
addrs.insert(taddr);
|
||||||
ui->listReceiveAddresses->addItem(taddr, 0);
|
ui->listReceiveAddresses->addItem(taddr, CAmount::fromqint64(0));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1084,7 +1084,7 @@ void MainWindow::updateTAddrCombo(bool checked) {
|
|||||||
if (!addrs.contains(addr)) {
|
if (!addrs.contains(addr)) {
|
||||||
addrs.insert(addr);
|
addrs.insert(addr);
|
||||||
// Balance is zero since it has not been previously added
|
// Balance is zero since it has not been previously added
|
||||||
ui->listReceiveAddresses->addItem(addr, 0);
|
ui->listReceiveAddresses->addItem(addr, CAmount::fromqint64(0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1101,7 +1101,7 @@ void MainWindow::updateTAddrCombo(bool checked) {
|
|||||||
// 5. Add a last, disabled item if there are remaining items
|
// 5. Add a last, disabled item if there are remaining items
|
||||||
if (allTaddrs.size() > addrs.size()) {
|
if (allTaddrs.size() > addrs.size()) {
|
||||||
auto num = QString::number(allTaddrs.size() - addrs.size());
|
auto num = QString::number(allTaddrs.size() - addrs.size());
|
||||||
ui->listReceiveAddresses->addItem("-- " + num + " more --", 0);
|
ui->listReceiveAddresses->addItem("-- " + num + " more --", CAmount::fromqint64(0));
|
||||||
|
|
||||||
QStandardItemModel* model = qobject_cast<QStandardItemModel*>(ui->listReceiveAddresses->model());
|
QStandardItemModel* model = qobject_cast<QStandardItemModel*>(ui->listReceiveAddresses->model());
|
||||||
QStandardItem* item = model->findItems("--", Qt::MatchStartsWith)[0];
|
QStandardItem* item = model->findItems("--", Qt::MatchStartsWith)[0];
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ using json = nlohmann::json;
|
|||||||
// Struct used to hold destination info when sending a Tx.
|
// Struct used to hold destination info when sending a Tx.
|
||||||
struct ToFields {
|
struct ToFields {
|
||||||
QString addr;
|
QString addr;
|
||||||
qint64 amount;
|
CAmount amount;
|
||||||
QString memo;
|
QString memo;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ struct ToFields {
|
|||||||
struct Tx {
|
struct Tx {
|
||||||
QString fromAddr;
|
QString fromAddr;
|
||||||
QList<ToFields> toAddrs;
|
QList<ToFields> toAddrs;
|
||||||
qint64 fee;
|
CAmount fee;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
|
|||||||
@@ -73,7 +73,8 @@ void RequestDialog::showPaymentConfirmation(MainWindow* main, QString paymentURI
|
|||||||
req.txtFrom->setText(payInfo.addr);
|
req.txtFrom->setText(payInfo.addr);
|
||||||
req.txtMemo->setPlainText(payInfo.memo);
|
req.txtMemo->setPlainText(payInfo.memo);
|
||||||
req.txtAmount->setText(payInfo.amt);
|
req.txtAmount->setText(payInfo.amt);
|
||||||
req.txtAmountUSD->setText(Settings::getUSDFromZecAmount(req.txtAmount->text().toDouble()));
|
CAmount amount = CAmount::fromDecimalString(req.txtAmount->text());
|
||||||
|
req.txtAmountUSD->setText(amount.toDecimalUSDString());
|
||||||
|
|
||||||
req.buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Pay"));
|
req.buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Pay"));
|
||||||
|
|
||||||
@@ -112,9 +113,11 @@ void RequestDialog::showRequestZcash(MainWindow* main) {
|
|||||||
// Amount textbox
|
// Amount textbox
|
||||||
req.txtAmount->setValidator(main->getAmountValidator());
|
req.txtAmount->setValidator(main->getAmountValidator());
|
||||||
QObject::connect(req.txtAmount, &QLineEdit::textChanged, [=] (auto text) {
|
QObject::connect(req.txtAmount, &QLineEdit::textChanged, [=] (auto text) {
|
||||||
req.txtAmountUSD->setText(Settings::getUSDFromZecAmount(text.toDouble()));
|
CAmount amount = CAmount::fromDecimalString(text);
|
||||||
|
req.txtAmountUSD->setText(amount.toDecimalUSDString());
|
||||||
});
|
});
|
||||||
req.txtAmountUSD->setText(Settings::getUSDFromZecAmount(req.txtAmount->text().toDouble()));
|
CAmount amount = CAmount::fromDecimalString(req.txtAmount->text());
|
||||||
|
req.txtAmountUSD->setText(amount.toDecimalUSDString());
|
||||||
|
|
||||||
req.txtMemo->setAcceptButton(req.buttonBox->button(QDialogButtonBox::Ok));
|
req.txtMemo->setAcceptButton(req.buttonBox->button(QDialogButtonBox::Ok));
|
||||||
req.txtMemo->setLenDisplayLabel(req.lblMemoLen);
|
req.txtMemo->setLenDisplayLabel(req.lblMemoLen);
|
||||||
@@ -124,8 +127,9 @@ void RequestDialog::showRequestZcash(MainWindow* main) {
|
|||||||
|
|
||||||
if (d.exec() == QDialog::Accepted) {
|
if (d.exec() == QDialog::Accepted) {
|
||||||
// Construct a zcash Payment URI with the data and pay it immediately.
|
// Construct a zcash Payment URI with the data and pay it immediately.
|
||||||
|
CAmount amount = CAmount::fromDecimalString(req.txtAmount->text());
|
||||||
QString memoURI = "zcash:" + req.cmbMyAddress->currentText()
|
QString memoURI = "zcash:" + req.cmbMyAddress->currentText()
|
||||||
+ "?amt=" + Settings::getDecimalString(req.txtAmount->text().toDouble())
|
+ "?amt=" + amount.toDecimalString()
|
||||||
+ "&memo=" + QUrl::toPercentEncoding(req.txtMemo->toPlainText());
|
+ "&memo=" + QUrl::toPercentEncoding(req.txtMemo->toPlainText());
|
||||||
|
|
||||||
QString sendURI = "zcash:" + AddressBook::addressFromAddressLabel(req.txtFrom->text())
|
QString sendURI = "zcash:" + AddressBook::addressFromAddressLabel(req.txtFrom->text())
|
||||||
|
|||||||
114
src/sendtab.cpp
114
src/sendtab.cpp
@@ -61,15 +61,17 @@ void MainWindow::setupSendTab() {
|
|||||||
// Fee amount changed
|
// Fee amount changed
|
||||||
ui->minerFeeAmt->setReadOnly(true);
|
ui->minerFeeAmt->setReadOnly(true);
|
||||||
QObject::connect(ui->minerFeeAmt, &QLineEdit::textChanged, [=](auto txt) {
|
QObject::connect(ui->minerFeeAmt, &QLineEdit::textChanged, [=](auto txt) {
|
||||||
ui->lblMinerFeeUSD->setText(Settings::getUSDFromZecAmount(txt.toDouble()));
|
CAmount fee = CAmount::fromDecimalString(txt);
|
||||||
|
ui->lblMinerFeeUSD->setText(fee.toDecimalUSDString());
|
||||||
});
|
});
|
||||||
ui->minerFeeAmt->setText(Settings::getDecimalString(Settings::getMinerFee()));
|
ui->minerFeeAmt->setText(Settings::getMinerFee().toDecimalString());
|
||||||
|
|
||||||
// Set up focus enter to set fees
|
// Set up focus enter to set fees
|
||||||
QObject::connect(ui->tabWidget, &QTabWidget::currentChanged, [=] (int pos) {
|
QObject::connect(ui->tabWidget, &QTabWidget::currentChanged, [=] (int pos) {
|
||||||
if (pos == 1) {
|
if (pos == 1) {
|
||||||
QString txt = ui->minerFeeAmt->text();
|
QString txt = ui->minerFeeAmt->text();
|
||||||
ui->lblMinerFeeUSD->setText(Settings::getUSDFromZecAmount(txt.toDouble()));
|
QString feeUSD = CAmount::fromDecimalString(txt).toDecimalUSDString();
|
||||||
|
ui->lblMinerFeeUSD->setText(feeUSD);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -167,67 +169,15 @@ void MainWindow::updateLabelsAutoComplete() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::setDefaultPayFrom() {
|
void MainWindow::setDefaultPayFrom() {
|
||||||
auto findMax = [=] (QString startsWith) {
|
|
||||||
double max_amt = 0;
|
|
||||||
int idx = -1;
|
|
||||||
|
|
||||||
for (int i=0; i < ui->inputsCombo->count(); i++) {
|
|
||||||
auto addr = ui->inputsCombo->itemText(i);
|
|
||||||
if (addr.startsWith(startsWith)) {
|
|
||||||
auto amt = rpc->getModel()->getAllBalances().value(addr);
|
|
||||||
if (max_amt < amt) {
|
|
||||||
max_amt = amt;
|
|
||||||
idx = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return idx;
|
|
||||||
};
|
|
||||||
|
|
||||||
// By default, select the z-address with the most balance from the inputs combo
|
|
||||||
auto maxZ = findMax("z");
|
|
||||||
if (maxZ >= 0) {
|
|
||||||
ui->inputsCombo->setCurrentIndex(maxZ);
|
|
||||||
} else {
|
|
||||||
auto maxT = findMax("t");
|
|
||||||
maxT = maxT >= 0 ? maxT : 0;
|
|
||||||
ui->inputsCombo->setCurrentIndex(maxT);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void MainWindow::updateFromCombo() {
|
void MainWindow::updateFromCombo() {
|
||||||
if (!rpc)
|
// delete
|
||||||
return;
|
|
||||||
|
|
||||||
auto lastFromAddr = ui->inputsCombo->currentText();
|
|
||||||
|
|
||||||
ui->inputsCombo->clear();
|
|
||||||
auto i = rpc->getModel()->getAllBalances().constBegin();
|
|
||||||
|
|
||||||
// Add all the addresses into the inputs combo box
|
|
||||||
while (i != rpc->getModel()->getAllBalances().constEnd()) {
|
|
||||||
ui->inputsCombo->addItem(i.key(), i.value());
|
|
||||||
if (i.key() == lastFromAddr) ui->inputsCombo->setCurrentText(i.key());
|
|
||||||
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lastFromAddr.isEmpty()) {
|
|
||||||
setDefaultPayFrom();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ui->inputsCombo->setCurrentText(lastFromAddr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::inputComboTextChanged(int index) {
|
void MainWindow::inputComboTextChanged(int index) {
|
||||||
auto addr = ui->inputsCombo->itemText(index);
|
// delete
|
||||||
auto bal = rpc->getModel()->getAllBalances().value(addr);
|
|
||||||
auto balFmt = Settings::getZECDisplayFormat(bal);
|
|
||||||
|
|
||||||
ui->sendAddressBalance->setText(balFmt);
|
|
||||||
ui->sendAddressBalanceUSD->setText(Settings::getUSDFromZecAmount(bal));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -340,7 +290,8 @@ void MainWindow::addressChanged(int itemNumber, const QString& text) {
|
|||||||
|
|
||||||
void MainWindow::amountChanged(int item, const QString& text) {
|
void MainWindow::amountChanged(int item, const QString& text) {
|
||||||
auto usd = ui->sendToWidgets->findChild<QLabel*>(QString("AmtUSD") % QString::number(item));
|
auto usd = ui->sendToWidgets->findChild<QLabel*>(QString("AmtUSD") % QString::number(item));
|
||||||
usd->setText(Settings::getUSDFromZecAmount(text.toDouble()));
|
CAmount amt = CAmount::fromDecimalString(text);
|
||||||
|
usd->setText(amt.toDecimalUSDString());
|
||||||
|
|
||||||
// If there is a recurring payment, update the info there as well
|
// If there is a recurring payment, update the info there as well
|
||||||
if (sendTxRecurringInfo != nullptr) {
|
if (sendTxRecurringInfo != nullptr) {
|
||||||
@@ -434,7 +385,7 @@ void MainWindow::clearSendForm() {
|
|||||||
setMemoEnabled(1, false);
|
setMemoEnabled(1, false);
|
||||||
|
|
||||||
// Reset the fee
|
// Reset the fee
|
||||||
ui->minerFeeAmt->setText(Settings::getDecimalString(Settings::getMinerFee()));
|
ui->minerFeeAmt->setText(Settings::getMinerFee().toDecimalString());
|
||||||
|
|
||||||
// Start the deletion after the first item, since we want to keep 1 send field there all there
|
// Start the deletion after the first item, since we want to keep 1 send field there all there
|
||||||
for (int i=1; i < totalItems; i++) {
|
for (int i=1; i < totalItems; i++) {
|
||||||
@@ -461,24 +412,24 @@ void MainWindow::maxAmountChecked(int checked) {
|
|||||||
if (rpc == nullptr) return;
|
if (rpc == nullptr) return;
|
||||||
|
|
||||||
// Calculate maximum amount
|
// Calculate maximum amount
|
||||||
double sumAllAmounts = 0.0;
|
CAmount sumAllAmounts = CAmount::fromqint64(0);
|
||||||
// Calculate all other amounts
|
// Calculate all other amounts
|
||||||
int totalItems = ui->sendToWidgets->children().size() - 2; // The last one is a spacer, so ignore that
|
int totalItems = ui->sendToWidgets->children().size() - 2; // The last one is a spacer, so ignore that
|
||||||
// Start counting the sum skipping the first one, because the MAX button is on the first one, and we don't
|
// Start counting the sum skipping the first one, because the MAX button is on the first one, and we don't
|
||||||
// want to include it in the sum.
|
// want to include it in the sum.
|
||||||
for (int i=1; i < totalItems; i++) {
|
for (int i=1; i < totalItems; i++) {
|
||||||
auto amt = ui->sendToWidgets->findChild<QLineEdit*>(QString("Amount") % QString::number(i+1));
|
auto amt = ui->sendToWidgets->findChild<QLineEdit*>(QString("Amount") % QString::number(i+1));
|
||||||
sumAllAmounts += amt->text().toDouble();
|
sumAllAmounts = sumAllAmounts + CAmount::fromDecimalString(amt->text());
|
||||||
}
|
}
|
||||||
|
|
||||||
sumAllAmounts += Settings::getMinerFee();
|
sumAllAmounts = sumAllAmounts + Settings::getMinerFee();
|
||||||
|
|
||||||
auto addr = ui->inputsCombo->currentText();
|
auto addr = ui->inputsCombo->currentText();
|
||||||
|
|
||||||
auto maxamount = rpc->getModel()->getAllBalances().value(addr) - sumAllAmounts;
|
auto maxamount = rpc->getModel()->getAllBalances().value(addr) - sumAllAmounts;
|
||||||
maxamount = (maxamount < 0) ? 0 : maxamount;
|
maxamount = (maxamount.toqint64() < 0) ? CAmount::fromqint64(0) : maxamount;
|
||||||
|
|
||||||
ui->Amount1->setText(Settings::getDecimalString(maxamount));
|
ui->Amount1->setText(maxamount.toDecimalString());
|
||||||
} else if (checked == Qt::Unchecked) {
|
} else if (checked == Qt::Unchecked) {
|
||||||
// Just remove the readonly part, don't change the content
|
// Just remove the readonly part, don't change the content
|
||||||
ui->Amount1->setReadOnly(false);
|
ui->Amount1->setReadOnly(false);
|
||||||
@@ -494,7 +445,7 @@ Tx MainWindow::createTxFromSendPage() {
|
|||||||
|
|
||||||
// For each addr/amt in the sendTo tab
|
// For each addr/amt in the sendTo tab
|
||||||
int totalItems = ui->sendToWidgets->children().size() - 2; // The last one is a spacer, so ignore that
|
int totalItems = ui->sendToWidgets->children().size() - 2; // The last one is a spacer, so ignore that
|
||||||
qint64 totalAmt = 0;
|
CAmount totalAmt = CAmount::fromqint64(0);
|
||||||
for (int i=0; i < totalItems; i++) {
|
for (int i=0; i < totalItems; i++) {
|
||||||
QString addr = ui->sendToWidgets->findChild<QLineEdit*>(QString("Address") % QString::number(i+1))->text().trimmed();
|
QString addr = ui->sendToWidgets->findChild<QLineEdit*>(QString("Address") % QString::number(i+1))->text().trimmed();
|
||||||
// Remove label if it exists
|
// Remove label if it exists
|
||||||
@@ -506,15 +457,15 @@ Tx MainWindow::createTxFromSendPage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool ok;
|
bool ok;
|
||||||
qint64 amt;
|
CAmount amt;
|
||||||
|
|
||||||
// Make sure it parses
|
// Make sure it parses
|
||||||
amtStr.toDouble(&ok);
|
amtStr.toDouble(&ok);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
amt = -1;
|
amt = CAmount::fromqint64(-1);
|
||||||
} else {
|
} else {
|
||||||
amt = Settings::getAmountFromUserDecimalStr(amtStr);
|
amt = CAmount::fromDecimalString(amtStr);
|
||||||
totalAmt += amt;
|
totalAmt = totalAmt + amt;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString memo = ui->sendToWidgets->findChild<QLabel*>(QString("MemoTxt") % QString::number(i+1))->text().trimmed();
|
QString memo = ui->sendToWidgets->findChild<QLabel*>(QString("MemoTxt") % QString::number(i+1))->text().trimmed();
|
||||||
@@ -587,7 +538,7 @@ bool MainWindow::confirmTx(Tx tx, RecurringPaymentInfo* rpi) {
|
|||||||
|
|
||||||
// For each addr/amt/memo, construct the JSON and also build the confirm dialog box
|
// For each addr/amt/memo, construct the JSON and also build the confirm dialog box
|
||||||
int row = 0;
|
int row = 0;
|
||||||
double totalSpending = 0;
|
CAmount totalSpending = CAmount::fromqint64(0);
|
||||||
|
|
||||||
for (int i=0; i < tx.toAddrs.size(); i++) {
|
for (int i=0; i < tx.toAddrs.size(); i++) {
|
||||||
auto toAddr = tx.toAddrs[i];
|
auto toAddr = tx.toAddrs[i];
|
||||||
@@ -605,15 +556,15 @@ bool MainWindow::confirmTx(Tx tx, RecurringPaymentInfo* rpi) {
|
|||||||
// Amount (ZEC)
|
// Amount (ZEC)
|
||||||
auto Amt = new QLabel(confirm.sendToAddrs);
|
auto Amt = new QLabel(confirm.sendToAddrs);
|
||||||
Amt->setObjectName(QString("Amt") % QString::number(i + 1));
|
Amt->setObjectName(QString("Amt") % QString::number(i + 1));
|
||||||
Amt->setText(Settings::getZECDisplayFormat(toAddr.amount));
|
Amt->setText(toAddr.amount.toDecimalZECString());
|
||||||
Amt->setAlignment(Qt::AlignRight | Qt::AlignTrailing | Qt::AlignVCenter);
|
Amt->setAlignment(Qt::AlignRight | Qt::AlignTrailing | Qt::AlignVCenter);
|
||||||
confirm.gridLayout->addWidget(Amt, row, 1, 1, 1);
|
confirm.gridLayout->addWidget(Amt, row, 1, 1, 1);
|
||||||
totalSpending += toAddr.amount;
|
totalSpending = totalSpending + toAddr.amount;
|
||||||
|
|
||||||
// Amount (USD)
|
// Amount (USD)
|
||||||
auto AmtUSD = new QLabel(confirm.sendToAddrs);
|
auto AmtUSD = new QLabel(confirm.sendToAddrs);
|
||||||
AmtUSD->setObjectName(QString("AmtUSD") % QString::number(i + 1));
|
AmtUSD->setObjectName(QString("AmtUSD") % QString::number(i + 1));
|
||||||
AmtUSD->setText(Settings::getUSDFromZecAmount(toAddr.amount));
|
AmtUSD->setText(toAddr.amount.toDecimalUSDString());
|
||||||
AmtUSD->setAlignment(Qt::AlignRight | Qt::AlignTrailing | Qt::AlignVCenter);
|
AmtUSD->setAlignment(Qt::AlignRight | Qt::AlignTrailing | Qt::AlignVCenter);
|
||||||
confirm.gridLayout->addWidget(AmtUSD, row, 2, 1, 1);
|
confirm.gridLayout->addWidget(AmtUSD, row, 2, 1, 1);
|
||||||
|
|
||||||
@@ -655,8 +606,8 @@ bool MainWindow::confirmTx(Tx tx, RecurringPaymentInfo* rpi) {
|
|||||||
minerFee->setObjectName(QStringLiteral("minerFee"));
|
minerFee->setObjectName(QStringLiteral("minerFee"));
|
||||||
minerFee->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
|
minerFee->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
|
||||||
confirm.gridLayout->addWidget(minerFee, row, 1, 1, 1);
|
confirm.gridLayout->addWidget(minerFee, row, 1, 1, 1);
|
||||||
minerFee->setText(Settings::getZECDisplayFormat(tx.fee));
|
minerFee->setText(tx.fee.toDecimalZECString());
|
||||||
totalSpending += tx.fee;
|
totalSpending = totalSpending + tx.fee;
|
||||||
|
|
||||||
auto minerFeeUSD = new QLabel(confirm.sendToAddrs);
|
auto minerFeeUSD = new QLabel(confirm.sendToAddrs);
|
||||||
QSizePolicy sizePolicy1(QSizePolicy::Minimum, QSizePolicy::Preferred);
|
QSizePolicy sizePolicy1(QSizePolicy::Minimum, QSizePolicy::Preferred);
|
||||||
@@ -664,7 +615,7 @@ bool MainWindow::confirmTx(Tx tx, RecurringPaymentInfo* rpi) {
|
|||||||
minerFeeUSD->setObjectName(QStringLiteral("minerFeeUSD"));
|
minerFeeUSD->setObjectName(QStringLiteral("minerFeeUSD"));
|
||||||
minerFeeUSD->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
|
minerFeeUSD->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
|
||||||
confirm.gridLayout->addWidget(minerFeeUSD, row, 2, 1, 1);
|
confirm.gridLayout->addWidget(minerFeeUSD, row, 2, 1, 1);
|
||||||
minerFeeUSD->setText(Settings::getUSDFromZecAmount(tx.fee));
|
minerFeeUSD->setText(tx.fee.toDecimalUSDString());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recurring payment info, show only if there is exactly one destination address
|
// Recurring payment info, show only if there is exactly one destination address
|
||||||
@@ -683,9 +634,9 @@ bool MainWindow::confirmTx(Tx tx, RecurringPaymentInfo* rpi) {
|
|||||||
confirm.sendFrom->setText(fnSplitAddressForWrap(tx.fromAddr));
|
confirm.sendFrom->setText(fnSplitAddressForWrap(tx.fromAddr));
|
||||||
confirm.sendFrom->setFont(fixedFont);
|
confirm.sendFrom->setFont(fixedFont);
|
||||||
QString tooltip = tr("Current balance : ") +
|
QString tooltip = tr("Current balance : ") +
|
||||||
Settings::getZECUSDDisplayFormat(rpc->getModel()->getAllBalances().value(tx.fromAddr));
|
rpc->getModel()->getAllBalances().value(tx.fromAddr).toDecimalZECUSDString();
|
||||||
tooltip += "\n" + tr("Balance after this Tx: ") +
|
tooltip += "\n" + tr("Balance after this Tx: ") +
|
||||||
Settings::getZECUSDDisplayFormat(rpc->getModel()->getAllBalances().value(tx.fromAddr) - totalSpending);
|
(rpc->getModel()->getAllBalances().value(tx.fromAddr) - totalSpending).toDecimalZECUSDString();
|
||||||
confirm.sendFrom->setToolTip(tooltip);
|
confirm.sendFrom->setToolTip(tooltip);
|
||||||
|
|
||||||
// Show the dialog and submit it if the user confirms
|
// Show the dialog and submit it if the user confirms
|
||||||
@@ -769,13 +720,12 @@ QString MainWindow::doSendTxValidations(Tx tx) {
|
|||||||
|
|
||||||
// This technically shouldn't be possible, but issue #62 seems to have discovered a bug
|
// This technically shouldn't be possible, but issue #62 seems to have discovered a bug
|
||||||
// somewhere, so just add a check to make sure.
|
// somewhere, so just add a check to make sure.
|
||||||
if (toAddr.amount < 0) {
|
if (toAddr.amount.toqint64() < 0) {
|
||||||
return QString(tr("Amount for address '%1' is invalid!").arg(toAddr.addr));
|
return QString(tr("Amount for address '%1' is invalid!").arg(toAddr.addr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
return QString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::cancelButton() {
|
void MainWindow::cancelButton() {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
#include "camount.h"
|
||||||
|
|
||||||
Settings* Settings::instance = nullptr;
|
Settings* Settings::instance = nullptr;
|
||||||
|
|
||||||
@@ -178,66 +179,6 @@ void Settings::openTxInExplorer(QString txid) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
QString Settings::getUSDFormat(double usdAmt) {
|
|
||||||
return "$" + QLocale(QLocale::English).toString(usdAmt, 'f', 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QString Settings::getUSDFromZecAmount(qint64 bal) {
|
|
||||||
return getUSDFormat(bal * Settings::getInstance()->getZECPrice());
|
|
||||||
}
|
|
||||||
|
|
||||||
QString Settings::getDecimalString(qint64 amt) {
|
|
||||||
if (amt < 0) {
|
|
||||||
return "-" + Settings::getDecimalString(-1 * amt);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Zcash has 8 decimal places
|
|
||||||
int places = Settings::getNumberOfDecimalPlaces();
|
|
||||||
qint64 divider = QString("1" + QString("0").repeated(places)).toULongLong();
|
|
||||||
|
|
||||||
int wholePart = amt / divider;
|
|
||||||
int decimalPart = amt % divider;
|
|
||||||
|
|
||||||
QString r = QString::number(wholePart);
|
|
||||||
if (decimalPart > 0) {
|
|
||||||
QString decimalPartStr = QString::number(decimalPart);
|
|
||||||
QString leadingZeros = QString("0").repeated(places - decimalPartStr.length());
|
|
||||||
|
|
||||||
r = r + "." + leadingZeros + decimalPartStr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
qint64 Settings::getAmountFromUserDecimalStr(QString amt) {
|
|
||||||
int places = Settings::getNumberOfDecimalPlaces();
|
|
||||||
qint64 divider = QString("1" + QString("0").repeated(places)).toULongLong();
|
|
||||||
|
|
||||||
auto amtParts = amt.split(".");
|
|
||||||
qint64 r = amtParts[0].toULongLong() * divider;
|
|
||||||
if (amtParts.length() == 2) {
|
|
||||||
auto trailingZeros = QString("0").repeated(places - amtParts[1].length());
|
|
||||||
r += QString(amtParts[1] + trailingZeros).toULongLong();
|
|
||||||
}
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString Settings::getZECDisplayFormat(qint64 bal) {
|
|
||||||
// This is idiotic. Why doesn't QString have a way to do this?
|
|
||||||
return getDecimalString(bal) % " " % Settings::getTokenName();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString Settings::getZECUSDDisplayFormat(qint64 bal) {
|
|
||||||
auto usdFormat = getUSDFromZecAmount(bal);
|
|
||||||
if (!usdFormat.isEmpty())
|
|
||||||
return getZECDisplayFormat(bal) % " (" % usdFormat % ")";
|
|
||||||
else
|
|
||||||
return getZECDisplayFormat(bal);
|
|
||||||
}
|
|
||||||
|
|
||||||
const QString Settings::txidStatusMessage = QString(QObject::tr("Tx submitted (right click to copy) txid:"));
|
const QString Settings::txidStatusMessage = QString(QObject::tr("Tx submitted (right click to copy) txid:"));
|
||||||
|
|
||||||
QString Settings::getTokenName() {
|
QString Settings::getTokenName() {
|
||||||
@@ -256,8 +197,8 @@ QString Settings::getDonationAddr() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
double Settings::getMinerFee() {
|
CAmount Settings::getMinerFee() {
|
||||||
return 10000;
|
return CAmount::fromqint64(10000);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Settings::isValidSaplingPrivateKey(QString pk) {
|
bool Settings::isValidSaplingPrivateKey(QString pk) {
|
||||||
@@ -282,7 +223,8 @@ bool Settings::isValidAddress(QString addr) {
|
|||||||
|
|
||||||
// Get a pretty string representation of this Payment URI
|
// Get a pretty string representation of this Payment URI
|
||||||
QString Settings::paymentURIPretty(PaymentURI uri) {
|
QString Settings::paymentURIPretty(PaymentURI uri) {
|
||||||
return QString() + "Payment Request\n" + "Pay: " + uri.addr + "\nAmount: " + getZECDisplayFormat(uri.amt.toDouble())
|
CAmount amount = CAmount::fromDecimalString(uri.amt);
|
||||||
|
return QString() + "Payment Request\n" + "Pay: " + uri.addr + "\nAmount: " + amount.toDecimalZECString()
|
||||||
+ "\nMemo:" + QUrl::fromPercentEncoding(uri.memo.toUtf8());
|
+ "\nMemo:" + QUrl::fromPercentEncoding(uri.memo.toUtf8());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#define SETTINGS_H
|
#define SETTINGS_H
|
||||||
|
|
||||||
#include "precompiled.h"
|
#include "precompiled.h"
|
||||||
|
#include "camount.h"
|
||||||
|
|
||||||
struct Config {
|
struct Config {
|
||||||
QString server;
|
QString server;
|
||||||
@@ -80,20 +81,11 @@ public:
|
|||||||
static bool isZAddress(QString addr);
|
static bool isZAddress(QString addr);
|
||||||
static bool isTAddress(QString addr);
|
static bool isTAddress(QString addr);
|
||||||
|
|
||||||
static QString getDecimalString(qint64 zecamt);
|
|
||||||
static QString getUSDFormat(double usdAmt);
|
|
||||||
|
|
||||||
static QString getUSDFromZecAmount(qint64 zecamt);
|
|
||||||
static QString getZECDisplayFormat(qint64 zecamt);
|
|
||||||
static QString getZECUSDDisplayFormat(qint64 bal);
|
|
||||||
|
|
||||||
static qint64 getAmountFromUserDecimalStr(QString amt);
|
|
||||||
|
|
||||||
static QString getTokenName();
|
static QString getTokenName();
|
||||||
static QString getDonationAddr();
|
static QString getDonationAddr();
|
||||||
|
|
||||||
static QString getDefaultServer();
|
static QString getDefaultServer();
|
||||||
static double getMinerFee();
|
static CAmount getMinerFee();
|
||||||
|
|
||||||
static int getMaxMobileAppTxns() { return 30; }
|
static int getMaxMobileAppTxns() { return 30; }
|
||||||
|
|
||||||
|
|||||||
@@ -105,11 +105,11 @@ bool TxTableModel::exportToCsv(QString fileName) const {
|
|||||||
case Column::Confirmations: return QString::number(dat.confirmations);
|
case Column::Confirmations: return QString::number(dat.confirmations);
|
||||||
case Column::Amount: {
|
case Column::Amount: {
|
||||||
// Sum up all the amounts
|
// Sum up all the amounts
|
||||||
qint64 total = 0;
|
CAmount total = CAmount::fromqint64(0);
|
||||||
for (int i=0; i < dat.items.length(); i++) {
|
for (int i=0; i < dat.items.length(); i++) {
|
||||||
total += dat.items[i].amount;
|
total = total + dat.items[i].amount;
|
||||||
}
|
}
|
||||||
return Settings::getZECDisplayFormat(total);
|
return total.toDecimalZECString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -141,11 +141,11 @@ bool TxTableModel::exportToCsv(QString fileName) const {
|
|||||||
case Column::Confirmations: return QString("%1 Network Confirmations").arg(QString::number(dat.confirmations));
|
case Column::Confirmations: return QString("%1 Network Confirmations").arg(QString::number(dat.confirmations));
|
||||||
case Column::Amount: {
|
case Column::Amount: {
|
||||||
// Sum up all the amounts
|
// Sum up all the amounts
|
||||||
qint64 total = 0;
|
CAmount total = CAmount::fromqint64(0);
|
||||||
for (int i=0; i < dat.items.length(); i++) {
|
for (int i=0; i < dat.items.length(); i++) {
|
||||||
total += dat.items[i].amount;
|
total = total + dat.items[i].amount;
|
||||||
}
|
}
|
||||||
return Settings::getInstance()->getUSDFromZecAmount(total);
|
return total.toDecimalUSDString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -237,9 +237,9 @@ QString TxTableModel::getType(int row) const {
|
|||||||
QString TxTableModel::getAmt(int row) const {
|
QString TxTableModel::getAmt(int row) const {
|
||||||
auto dat = modeldata->at(row);
|
auto dat = modeldata->at(row);
|
||||||
|
|
||||||
qint64 total = 0;
|
CAmount total = CAmount::fromqint64(0);
|
||||||
for (int i=0; i < dat.items.length(); i++) {
|
for (int i=0; i < dat.items.length(); i++) {
|
||||||
total += dat.items[i].amount;
|
total = total + dat.items[i].amount;
|
||||||
}
|
}
|
||||||
return Settings::getDecimalString(total);
|
return total.toDecimalString();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "viewalladdresses.h"
|
#include "viewalladdresses.h"
|
||||||
|
#include "camount.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
|
||||||
ViewAllAddressesModel::ViewAllAddressesModel(QTableView *parent, QList<QString> taddrs, Controller* rpc)
|
ViewAllAddressesModel::ViewAllAddressesModel(QTableView *parent, QList<QString> taddrs, Controller* rpc)
|
||||||
@@ -22,7 +23,7 @@ QVariant ViewAllAddressesModel::data(const QModelIndex &index, int role) const {
|
|||||||
if (role == Qt::DisplayRole) {
|
if (role == Qt::DisplayRole) {
|
||||||
switch(index.column()) {
|
switch(index.column()) {
|
||||||
case 0: return address;
|
case 0: return address;
|
||||||
case 1: return rpc->getModel()->getAllBalances().value(address, 0.0);
|
case 1: return rpc->getModel()->getAllBalances().value(address, CAmount::fromqint64(0)).toDecimalString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
|||||||
@@ -658,9 +658,9 @@ void AppDataServer::processSendTx(QJsonObject sendTx, MainWindow* mainwindow, st
|
|||||||
tx.fee = Settings::getMinerFee();
|
tx.fee = Settings::getMinerFee();
|
||||||
|
|
||||||
// Find a from address that has at least the sending amout
|
// Find a from address that has at least the sending amout
|
||||||
qint64 amt = Settings::getAmountFromUserDecimalStr(sendTx["amount"].toString());
|
CAmount amt = CAmount::fromDecimalString(sendTx["amount"].toString());
|
||||||
auto allBalances = mainwindow->getRPC()->getModel()->getAllBalances();
|
auto allBalances = mainwindow->getRPC()->getModel()->getAllBalances();
|
||||||
QList<QPair<QString, double>> bals;
|
QList<QPair<QString, CAmount>> bals;
|
||||||
for (auto i : allBalances.keys()) {
|
for (auto i : allBalances.keys()) {
|
||||||
// Filter out sprout addresses
|
// Filter out sprout addresses
|
||||||
if (Settings::getInstance()->isSproutAddress(i))
|
if (Settings::getInstance()->isSproutAddress(i))
|
||||||
@@ -669,7 +669,7 @@ void AppDataServer::processSendTx(QJsonObject sendTx, MainWindow* mainwindow, st
|
|||||||
if (allBalances.value(i) < amt)
|
if (allBalances.value(i) < amt)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
bals.append(QPair<QString, double>(i, allBalances.value(i)));
|
bals.append(QPair<QString, CAmount>(i, allBalances.value(i)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bals.isEmpty()) {
|
if (bals.isEmpty()) {
|
||||||
@@ -677,7 +677,7 @@ void AppDataServer::processSendTx(QJsonObject sendTx, MainWindow* mainwindow, st
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::sort(bals.begin(), bals.end(), [=](const QPair<QString, double>a, const QPair<QString, double> b) -> bool {
|
std::sort(bals.begin(), bals.end(), [=](const QPair<QString, CAmount>a, const QPair<QString, CAmount> b) -> bool {
|
||||||
// Sort z addresses first
|
// Sort z addresses first
|
||||||
return a.first > b.first;
|
return a.first > b.first;
|
||||||
});
|
});
|
||||||
@@ -736,8 +736,8 @@ void AppDataServer::processGetInfo(QJsonObject jobj, MainWindow* mainWindow, std
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Max spendable safely from a z address and from any address
|
// Max spendable safely from a z address and from any address
|
||||||
double maxZSpendable = 0;
|
CAmount maxZSpendable = CAmount::fromqint64(0);
|
||||||
double maxSpendable = 0;
|
CAmount maxSpendable = CAmount::fromqint64(0);
|
||||||
for (auto a : mainWindow->getRPC()->getModel()->getAllBalances().keys()) {
|
for (auto a : mainWindow->getRPC()->getModel()->getAllBalances().keys()) {
|
||||||
if (Settings::getInstance()->isSaplingAddress(a)) {
|
if (Settings::getInstance()->isSaplingAddress(a)) {
|
||||||
if (mainWindow->getRPC()->getModel()->getAllBalances().value(a) > maxZSpendable) {
|
if (mainWindow->getRPC()->getModel()->getAllBalances().value(a) > maxZSpendable) {
|
||||||
@@ -751,14 +751,14 @@ void AppDataServer::processGetInfo(QJsonObject jobj, MainWindow* mainWindow, std
|
|||||||
|
|
||||||
setConnectedName(connectedName);
|
setConnectedName(connectedName);
|
||||||
|
|
||||||
auto r = QJsonDocument(QJsonObject{
|
auto r = QJsonDocument(QJsonObject {
|
||||||
{"version", 1.0},
|
{"version", 1.0},
|
||||||
{"command", "getInfo"},
|
{"command", "getInfo"},
|
||||||
{"saplingAddress", mainWindow->getRPC()->getDefaultSaplingAddress()},
|
{"saplingAddress", mainWindow->getRPC()->getDefaultSaplingAddress()},
|
||||||
{"tAddress", mainWindow->getRPC()->getDefaultTAddress()},
|
{"tAddress", mainWindow->getRPC()->getDefaultTAddress()},
|
||||||
{"balance", AppDataModel::getInstance()->getTotalBalance()},
|
{"balance", AppDataModel::getInstance()->getTotalBalance().toDecimalDouble()},
|
||||||
{"maxspendable", maxSpendable},
|
{"maxspendable", maxSpendable.toDecimalDouble()},
|
||||||
{"maxzspendable", maxZSpendable},
|
{"maxzspendable", maxZSpendable.toDecimalDouble()},
|
||||||
{"tokenName", Settings::getTokenName()},
|
{"tokenName", Settings::getTokenName()},
|
||||||
{"zecprice", Settings::getInstance()->getZECPrice()},
|
{"zecprice", Settings::getInstance()->getZECPrice()},
|
||||||
{"serverversion", QString(APP_VERSION)}
|
{"serverversion", QString(APP_VERSION)}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "precompiled.h"
|
#include "precompiled.h"
|
||||||
|
|
||||||
|
#include "camount.h"
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "ui_mobileappconnector.h"
|
#include "ui_mobileappconnector.h"
|
||||||
|
|
||||||
@@ -151,11 +152,11 @@ public:
|
|||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
double getTBalance() { return balTransparent; }
|
CAmount getTBalance() { return balTransparent; }
|
||||||
double getZBalance() { return balShielded; }
|
CAmount getZBalance() { return balShielded; }
|
||||||
double getTotalBalance() { return balTotal; }
|
CAmount getTotalBalance() { return balTotal; }
|
||||||
|
|
||||||
void setBalances(double transparent, double shielded) {
|
void setBalances(CAmount transparent, CAmount shielded) {
|
||||||
balTransparent = transparent;
|
balTransparent = transparent;
|
||||||
balShielded = shielded;
|
balShielded = shielded;
|
||||||
balTotal = balTransparent + balShielded;
|
balTotal = balTransparent + balShielded;
|
||||||
@@ -164,9 +165,9 @@ public:
|
|||||||
private:
|
private:
|
||||||
AppDataModel() = default; // Private, for singleton
|
AppDataModel() = default; // Private, for singleton
|
||||||
|
|
||||||
double balTransparent;
|
CAmount balTransparent;
|
||||||
double balShielded;
|
CAmount balShielded;
|
||||||
double balTotal;
|
CAmount balTotal;
|
||||||
|
|
||||||
QString saplingAddress;
|
QString saplingAddress;
|
||||||
|
|
||||||
|
|||||||
@@ -60,7 +60,8 @@ SOURCES += \
|
|||||||
src/viewalladdresses.cpp \
|
src/viewalladdresses.cpp \
|
||||||
src/datamodel.cpp \
|
src/datamodel.cpp \
|
||||||
src/controller.cpp \
|
src/controller.cpp \
|
||||||
src/liteinterface.cpp
|
src/liteinterface.cpp \
|
||||||
|
src/camount.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
src/firsttimewizard.h \
|
src/firsttimewizard.h \
|
||||||
@@ -88,6 +89,7 @@ HEADERS += \
|
|||||||
src/datamodel.h \
|
src/datamodel.h \
|
||||||
src/controller.h \
|
src/controller.h \
|
||||||
src/liteinterface.h \
|
src/liteinterface.h \
|
||||||
|
src/camount.h \
|
||||||
lib/zecwalletlitelib.h
|
lib/zecwalletlitelib.h
|
||||||
|
|
||||||
FORMS += \
|
FORMS += \
|
||||||
@@ -110,7 +112,7 @@ FORMS += \
|
|||||||
src/recurringdialog.ui \
|
src/recurringdialog.ui \
|
||||||
src/newrecurring.ui \
|
src/newrecurring.ui \
|
||||||
src/requestdialog.ui \
|
src/requestdialog.ui \
|
||||||
src/recurringmultiple.ui
|
src/recurringmultiple.ui
|
||||||
|
|
||||||
|
|
||||||
TRANSLATIONS = res/zec_qt_wallet_es.ts \
|
TRANSLATIONS = res/zec_qt_wallet_es.ts \
|
||||||
|
|||||||
Reference in New Issue
Block a user