Add transactions fetch
This commit is contained in:
@@ -2,7 +2,6 @@
|
||||
|
||||
#include "addressbook.h"
|
||||
#include "settings.h"
|
||||
#include "senttxstore.h"
|
||||
#include "version.h"
|
||||
#include "websockets.h"
|
||||
|
||||
@@ -143,9 +142,7 @@ void Controller::noConnection() {
|
||||
|
||||
// Clear Transactions table.
|
||||
QList<TransactionItem> emptyTxs;
|
||||
transactionsTableModel->addTData(emptyTxs);
|
||||
transactionsTableModel->addZRecvData(emptyTxs);
|
||||
transactionsTableModel->addZSentData(emptyTxs);
|
||||
transactionsTableModel->replaceData(emptyTxs);
|
||||
|
||||
// Clear balances
|
||||
ui->balSheilded->setText("");
|
||||
@@ -160,28 +157,6 @@ void Controller::noConnection() {
|
||||
ui->inputsCombo->clear();
|
||||
}
|
||||
|
||||
// Refresh received z txs by calling z_listreceivedbyaddress/gettransaction
|
||||
void Controller::refreshReceivedZTrans(QList<QString> zaddrs) {
|
||||
if (!zrpc->haveConnection())
|
||||
return noConnection();
|
||||
|
||||
// We'll only refresh the received Z txs if settings allows us.
|
||||
if (!Settings::getInstance()->getSaveZtxs()) {
|
||||
QList<TransactionItem> emptylist;
|
||||
transactionsTableModel->addZRecvData(emptylist);
|
||||
return;
|
||||
}
|
||||
|
||||
zrpc->fetchReceivedZTrans(zaddrs,
|
||||
[=] (QString addr) {
|
||||
model->markAddressUsed(addr);
|
||||
},
|
||||
[=] (QList<TransactionItem> txdata) {
|
||||
transactionsTableModel->addZRecvData(txdata);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/// This will refresh all the balance data from zcashd
|
||||
void Controller::refresh(bool force) {
|
||||
if (!zrpc->haveConnection())
|
||||
@@ -190,7 +165,6 @@ void Controller::refresh(bool force) {
|
||||
getInfoThenRefresh(force);
|
||||
}
|
||||
|
||||
|
||||
void Controller::getInfoThenRefresh(bool force) {
|
||||
if (!zrpc->haveConnection())
|
||||
return noConnection();
|
||||
@@ -275,8 +249,7 @@ void Controller::refreshAddresses() {
|
||||
model->replaceTaddresses(newtaddresses);
|
||||
|
||||
// Refresh the sent and received txs from all these z-addresses
|
||||
refreshSentZTrans();
|
||||
refreshReceivedZTrans(model->getAllZAddresses());
|
||||
refreshTransactions();
|
||||
});
|
||||
|
||||
}
|
||||
@@ -362,57 +335,64 @@ void Controller::refreshTransactions() {
|
||||
|
||||
zrpc->fetchTransactions([=] (json reply) {
|
||||
QList<TransactionItem> txdata;
|
||||
|
||||
|
||||
for (auto& it : reply.get<json::array_t>()) {
|
||||
double fee = 0;
|
||||
if (!it["fee"].is_null()) {
|
||||
fee = it["fee"].get<json::number_float_t>();
|
||||
}
|
||||
QString address;
|
||||
qint64 total_amount;
|
||||
QList<TransactionItemDetail> items;
|
||||
|
||||
QString address = (it["address"].is_null() ? "" : QString::fromStdString(it["address"]));
|
||||
// First, check if there's outgoing metadata
|
||||
if (!it["outgoing_metadata"].is_null()) {
|
||||
|
||||
for (auto o: it["outgoing_metadata"].get<json::array_t>()) {
|
||||
QString address = QString::fromStdString(o["address"]);
|
||||
qint64 amount = o["value"].get<json::number_unsigned_t>();
|
||||
|
||||
QString memo;
|
||||
if (!o["memo"].is_null()) {
|
||||
memo = QString::fromStdString(o["memo"]);
|
||||
}
|
||||
|
||||
TransactionItem tx{
|
||||
QString::fromStdString(it["category"]),
|
||||
(qint64)it["time"].get<json::number_unsigned_t>(),
|
||||
address,
|
||||
QString::fromStdString(it["txid"]),
|
||||
it["amount"].get<json::number_float_t>() + fee,
|
||||
static_cast<long>(it["confirmations"].get<json::number_unsigned_t>()),
|
||||
"", "" };
|
||||
items.push_back(TransactionItemDetail{address, amount, memo});
|
||||
total_amount += amount;
|
||||
}
|
||||
|
||||
txdata.push_back(tx);
|
||||
if (!address.isEmpty())
|
||||
if (items.length() == 1) {
|
||||
address = items[0].address;
|
||||
} else {
|
||||
address = "(Multiple)";
|
||||
}
|
||||
|
||||
txdata.push_back(TransactionItem{
|
||||
"Sent",
|
||||
it["block_height"].get<json::number_unsigned_t>(),
|
||||
address,
|
||||
QString::fromStdString(it["txid"]),
|
||||
1,
|
||||
items
|
||||
});
|
||||
} else {
|
||||
// Incoming Transaction
|
||||
address = (it["address"].is_null() ? "" : QString::fromStdString(it["address"]));
|
||||
model->markAddressUsed(address);
|
||||
|
||||
TransactionItem tx{
|
||||
"Receive",
|
||||
it["block_height"].get<json::number_unsigned_t>(),
|
||||
address,
|
||||
QString::fromStdString(it["txid"]),
|
||||
1,
|
||||
items
|
||||
};
|
||||
|
||||
txdata.push_back(tx);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Update model data, which updates the table view
|
||||
transactionsTableModel->addTData(txdata);
|
||||
});
|
||||
}
|
||||
|
||||
// Read sent Z transactions from the file.
|
||||
void Controller::refreshSentZTrans() {
|
||||
if (!zrpc->haveConnection())
|
||||
return noConnection();
|
||||
|
||||
auto sentZTxs = SentTxStore::readSentTxFile();
|
||||
|
||||
// If there are no sent z txs, then empty the table.
|
||||
// This happens when you clear history.
|
||||
if (sentZTxs.isEmpty()) {
|
||||
transactionsTableModel->addZSentData(sentZTxs);
|
||||
return;
|
||||
}
|
||||
|
||||
QList<QString> txids;
|
||||
|
||||
for (auto sentTx: sentZTxs) {
|
||||
txids.push_back(sentTx.txid);
|
||||
}
|
||||
|
||||
// Look up all the txids to get the confirmation count for them.
|
||||
zrpc->fetchReceivedTTrans(txids, sentZTxs, [=](auto newSentZTxs) {
|
||||
transactionsTableModel->addZSentData(newSentZTxs);
|
||||
transactionsTableModel->replaceData(txdata);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -485,8 +465,6 @@ void Controller::watchTxStatus() {
|
||||
|
||||
if (status == "success") {
|
||||
auto txid = QString::fromStdString(it["result"]["txid"]);
|
||||
|
||||
SentTxStore::addToSentTx(watchingOps[id].tx, txid);
|
||||
|
||||
auto wtx = watchingOps[id];
|
||||
watchingOps.remove(id);
|
||||
|
||||
@@ -86,8 +86,6 @@ private:
|
||||
void refreshBalances();
|
||||
|
||||
void refreshTransactions();
|
||||
void refreshSentZTrans();
|
||||
void refreshReceivedZTrans(QList<QString> zaddresses);
|
||||
|
||||
bool processUnspent (const json& reply, QMap<QString, qint64>* newBalances, QList<UnspentOutput>* newUtxos);
|
||||
void updateUI (bool anyUnconfirmed);
|
||||
|
||||
@@ -155,13 +155,7 @@ void LiteInterface::fetchTransactions(const std::function<void(json)>& cb) {
|
||||
if (conn == nullptr)
|
||||
return;
|
||||
|
||||
// json payload = {
|
||||
// {"jsonrpc", "1.0"},
|
||||
// {"id", "someid"},
|
||||
// {"method", "listtransactions"}
|
||||
// };
|
||||
|
||||
// conn->doRPCWithDefaultErrorHandling(payload, cb);
|
||||
conn->doRPCWithDefaultErrorHandling("list", "", cb);
|
||||
}
|
||||
|
||||
void LiteInterface::sendZTransaction(json params, const std::function<void(json)>& cb,
|
||||
|
||||
@@ -7,15 +7,24 @@
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
// Since each transaction can contain multiple outputs, we separate them out individually
|
||||
// into a struct with address, amount, memo
|
||||
struct TransactionItemDetail {
|
||||
QString address;
|
||||
qint64 amount;
|
||||
QString memo;
|
||||
};
|
||||
|
||||
// Represents a row in the transactions table. Note that each transaction can contain
|
||||
// multiple addresses (i.e., Multiple TransctionItemDetail)
|
||||
struct TransactionItem {
|
||||
QString type;
|
||||
qint64 datetime;
|
||||
QString address;
|
||||
QString txid;
|
||||
double amount;
|
||||
long confirmations;
|
||||
QString fromAddr;
|
||||
QString memo;
|
||||
|
||||
QList<TransactionItemDetail> items;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
#include "balancestablemodel.h"
|
||||
#include "settings.h"
|
||||
#include "version.h"
|
||||
#include "senttxstore.h"
|
||||
#include "connection.h"
|
||||
#include "requestdialog.h"
|
||||
#include "websockets.h"
|
||||
@@ -275,17 +274,6 @@ void MainWindow::setupSettingsModal() {
|
||||
Settings::getInstance()->setSaveZtxs(checked);
|
||||
});
|
||||
|
||||
// Setup clear button
|
||||
QObject::connect(settings.btnClearSaved, &QCheckBox::clicked, [=]() {
|
||||
if (QMessageBox::warning(this, "Clear saved history?",
|
||||
"Shielded z-Address transactions are stored locally in your wallet, outside zcashd. You may delete this saved information safely any time for your privacy.\nDo you want to delete the saved shielded transactions now?",
|
||||
QMessageBox::Yes, QMessageBox::Cancel)) {
|
||||
SentTxStore::deleteHistory();
|
||||
// Reload after the clear button so existing txs disappear
|
||||
rpc->refresh(true);
|
||||
}
|
||||
});
|
||||
|
||||
// Setup theme combo
|
||||
int theme_index = settings.comboBoxTheme->findText(Settings::getInstance()->get_theme_name(), Qt::MatchExactly);
|
||||
settings.comboBoxTheme->setCurrentIndex(theme_index);
|
||||
|
||||
@@ -1,115 +0,0 @@
|
||||
#include "senttxstore.h"
|
||||
#include "settings.h"
|
||||
|
||||
/// Get the location of the app data file to be written.
|
||||
QString SentTxStore::writeableFile() {
|
||||
auto filename = QStringLiteral("senttxstore.dat");
|
||||
|
||||
auto dir = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));
|
||||
if (!dir.exists())
|
||||
QDir().mkpath(dir.absolutePath());
|
||||
|
||||
if (Settings::getInstance()->isTestnet()) {
|
||||
return dir.filePath("testnet-" % filename);
|
||||
} else {
|
||||
return dir.filePath(filename);
|
||||
}
|
||||
}
|
||||
|
||||
// delete the sent history.
|
||||
void SentTxStore::deleteHistory() {
|
||||
QFile data(writeableFile());
|
||||
data.remove();
|
||||
data.close();
|
||||
}
|
||||
|
||||
QList<TransactionItem> SentTxStore::readSentTxFile() {
|
||||
QFile data(writeableFile());
|
||||
if (!data.exists()) {
|
||||
return QList<TransactionItem>();
|
||||
}
|
||||
|
||||
QJsonDocument jsonDoc;
|
||||
|
||||
data.open(QFile::ReadOnly);
|
||||
jsonDoc = QJsonDocument::fromJson(data.readAll());
|
||||
data.close();
|
||||
|
||||
QList<TransactionItem> items;
|
||||
|
||||
for (auto i : jsonDoc.array()) {
|
||||
auto sentTx = i.toObject();
|
||||
TransactionItem t{"send", (qint64)sentTx["datetime"].toVariant().toLongLong(),
|
||||
sentTx["address"].toString(),
|
||||
sentTx["txid"].toString(),
|
||||
sentTx["amount"].toDouble() + sentTx["fee"].toDouble(),
|
||||
0, sentTx["from"].toString(), ""};
|
||||
items.push_back(t);
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
void SentTxStore::addToSentTx(Tx tx, QString txid) {
|
||||
// Save transactions only if the settings are allowed
|
||||
if (!Settings::getInstance()->getSaveZtxs())
|
||||
return;
|
||||
|
||||
// Also, only store outgoing txs where the from address is a z-Addr. Else, regular zcashd
|
||||
// stores it just fine
|
||||
if (! Settings::isZAddress(tx.fromAddr))
|
||||
return;
|
||||
|
||||
QFile data(writeableFile());
|
||||
QJsonDocument jsonDoc;
|
||||
|
||||
// If data doesn't exist, then create a blank one
|
||||
if (!data.exists()) {
|
||||
QJsonArray a;
|
||||
jsonDoc.setArray(a);
|
||||
|
||||
QFile newFile(writeableFile());
|
||||
newFile.open(QFile::WriteOnly);
|
||||
newFile.write(jsonDoc.toJson());
|
||||
newFile.close();
|
||||
} else {
|
||||
data.open(QFile::ReadOnly);
|
||||
jsonDoc = QJsonDocument().fromJson(data.readAll());
|
||||
data.close();
|
||||
}
|
||||
|
||||
// Calculate total amount in this tx
|
||||
double totalAmount = 0;
|
||||
for (auto i : tx.toAddrs) {
|
||||
totalAmount += i.amount;
|
||||
}
|
||||
|
||||
QString toAddresses;
|
||||
if (tx.toAddrs.length() == 1) {
|
||||
toAddresses = tx.toAddrs[0].addr;
|
||||
} else {
|
||||
// Concatenate all the toAddresses
|
||||
for (auto a : tx.toAddrs) {
|
||||
toAddresses += a.addr % "(" % Settings::getZECDisplayFormat(a.amount) % ") ";
|
||||
}
|
||||
}
|
||||
|
||||
auto list = jsonDoc.array();
|
||||
QJsonObject txItem;
|
||||
txItem["type"] = "sent";
|
||||
txItem["from"] = tx.fromAddr;
|
||||
txItem["datetime"] = QDateTime::currentMSecsSinceEpoch() / (qint64)1000;
|
||||
txItem["address"] = toAddresses;
|
||||
txItem["txid"] = txid;
|
||||
txItem["amount"] = -totalAmount;
|
||||
txItem["fee"] = -tx.fee;
|
||||
list.append(txItem);
|
||||
|
||||
jsonDoc.setArray(list);
|
||||
|
||||
QFile writer(writeableFile());
|
||||
if (writer.open(QFile::WriteOnly | QFile::Truncate)) {
|
||||
writer.write(jsonDoc.toJson());
|
||||
}
|
||||
writer.close();
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
#ifndef SENTTXSTORE_H
|
||||
#define SENTTXSTORE_H
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "mainwindow.h"
|
||||
#include "controller.h"
|
||||
|
||||
class SentTxStore {
|
||||
public:
|
||||
static void deleteHistory();
|
||||
|
||||
static QList<TransactionItem> readSentTxFile();
|
||||
static void addToSentTx(Tx tx, QString txid);
|
||||
|
||||
private:
|
||||
static QString writeableFile();
|
||||
|
||||
};
|
||||
|
||||
#endif // SENTTXSTORE_H
|
||||
@@ -9,34 +9,15 @@ TxTableModel::TxTableModel(QObject *parent)
|
||||
|
||||
TxTableModel::~TxTableModel() {
|
||||
delete modeldata;
|
||||
delete tTrans;
|
||||
delete zsTrans;
|
||||
delete zrTrans;
|
||||
}
|
||||
|
||||
void TxTableModel::addZSentData(const QList<TransactionItem>& data) {
|
||||
delete zsTrans;
|
||||
zsTrans = new QList<TransactionItem>();
|
||||
std::copy(data.begin(), data.end(), std::back_inserter(*zsTrans));
|
||||
void TxTableModel::replaceData(const QList<TransactionItem>& data) {
|
||||
delete modeldata;
|
||||
modeldata = new QList<TransactionItem>();
|
||||
std::copy(data.begin(), data.end(), std::back_inserter(*modeldata));
|
||||
|
||||
updateAllData();
|
||||
}
|
||||
|
||||
void TxTableModel::addZRecvData(const QList<TransactionItem>& data) {
|
||||
delete zrTrans;
|
||||
zrTrans = new QList<TransactionItem>();
|
||||
std::copy(data.begin(), data.end(), std::back_inserter(*zrTrans));
|
||||
|
||||
updateAllData();
|
||||
}
|
||||
|
||||
|
||||
void TxTableModel::addTData(const QList<TransactionItem>& data) {
|
||||
delete tTrans;
|
||||
tTrans = new QList<TransactionItem>();
|
||||
std::copy(data.begin(), data.end(), std::back_inserter(*tTrans));
|
||||
|
||||
updateAllData();
|
||||
dataChanged(index(0, 0), index(modeldata->size()-1, columnCount(index(0,0))-1));
|
||||
layoutChanged();
|
||||
}
|
||||
|
||||
bool TxTableModel::exportToCsv(QString fileName) const {
|
||||
@@ -61,8 +42,9 @@ bool TxTableModel::exportToCsv(QString fileName) const {
|
||||
for (int col = 0; col < headers.length(); col++) {
|
||||
out << "\"" << data(index(row, col), Qt::DisplayRole).toString() << "\",";
|
||||
}
|
||||
|
||||
// Memo
|
||||
out << "\"" << modeldata->at(row).memo << "\"";
|
||||
out << "\"" << this->getMemo(row) << "\"";
|
||||
out << endl;
|
||||
}
|
||||
|
||||
@@ -70,25 +52,6 @@ bool TxTableModel::exportToCsv(QString fileName) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
void TxTableModel::updateAllData() {
|
||||
auto newmodeldata = new QList<TransactionItem>();
|
||||
|
||||
if (tTrans != nullptr) std::copy( tTrans->begin(), tTrans->end(), std::back_inserter(*newmodeldata));
|
||||
if (zsTrans != nullptr) std::copy(zsTrans->begin(), zsTrans->end(), std::back_inserter(*newmodeldata));
|
||||
if (zrTrans != nullptr) std::copy(zrTrans->begin(), zrTrans->end(), std::back_inserter(*newmodeldata));
|
||||
|
||||
// Sort by reverse time
|
||||
std::sort(newmodeldata->begin(), newmodeldata->end(), [=] (auto a, auto b) {
|
||||
return a.datetime > b.datetime; // reverse sort
|
||||
});
|
||||
|
||||
// And then swap out the modeldata with the new one.
|
||||
delete modeldata;
|
||||
modeldata = newmodeldata;
|
||||
|
||||
dataChanged(index(0, 0), index(modeldata->size()-1, columnCount(index(0,0))-1));
|
||||
layoutChanged();
|
||||
}
|
||||
|
||||
int TxTableModel::rowCount(const QModelIndex&) const
|
||||
{
|
||||
@@ -135,18 +98,31 @@ void TxTableModel::updateAllData() {
|
||||
}
|
||||
case Column::Time: return QDateTime::fromMSecsSinceEpoch(dat.datetime * (qint64)1000).toLocalTime().toString();
|
||||
case Column::Confirmations: return QString::number(dat.confirmations);
|
||||
case Column::Amount: return Settings::getZECDisplayFormat(dat.amount);
|
||||
case Column::Amount: {
|
||||
// Sum up all the amounts
|
||||
qint64 total = 0;
|
||||
for (int i=0; i < dat.items.length(); i++) {
|
||||
total += dat.items[i].amount;
|
||||
}
|
||||
return Settings::getZECDisplayFormat(total);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (role == Qt::ToolTipRole) {
|
||||
switch (index.column()) {
|
||||
case Column::Type: {
|
||||
if (dat.memo.startsWith("zcash:")) {
|
||||
return Settings::paymentURIPretty(Settings::parseURI(dat.memo));
|
||||
// If there are multiple memos, then mark them as such
|
||||
if (dat.items.length() == 1) {
|
||||
auto memo = dat.items[0].memo;
|
||||
if (memo.startsWith("zcash:")) {
|
||||
return Settings::paymentURIPretty(Settings::parseURI(memo));
|
||||
} else {
|
||||
return modeldata->at(index.row()).type +
|
||||
(memo.isEmpty() ? "" : " tx memo: \"" + memo + "\"");
|
||||
}
|
||||
} else {
|
||||
return modeldata->at(index.row()).type +
|
||||
(dat.memo.isEmpty() ? "" : " tx memo: \"" + dat.memo + "\"");
|
||||
return "Multiple";
|
||||
}
|
||||
}
|
||||
case Column::Address: {
|
||||
@@ -158,21 +134,33 @@ void TxTableModel::updateAllData() {
|
||||
}
|
||||
case Column::Time: return QDateTime::fromMSecsSinceEpoch(modeldata->at(index.row()).datetime * (qint64)1000).toLocalTime().toString();
|
||||
case Column::Confirmations: return QString("%1 Network Confirmations").arg(QString::number(dat.confirmations));
|
||||
case Column::Amount: return Settings::getInstance()->getUSDFromZecAmount(modeldata->at(index.row()).amount);
|
||||
case Column::Amount: {
|
||||
// Sum up all the amounts
|
||||
qint64 total = 0;
|
||||
for (int i=0; i < dat.items.length(); i++) {
|
||||
total += dat.items[i].amount;
|
||||
}
|
||||
return Settings::getInstance()->getUSDFromZecAmount(total);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (role == Qt::DecorationRole && index.column() == 0) {
|
||||
if (!dat.memo.isEmpty()) {
|
||||
// If the memo is a Payment URI, then show a payment request icon
|
||||
if (dat.memo.startsWith("zcash:")) {
|
||||
QIcon icon(":/icons/res/paymentreq.gif");
|
||||
return QVariant(icon.pixmap(16, 16));
|
||||
} else {
|
||||
// Return the info pixmap to indicate memo
|
||||
QIcon icon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxInformation);
|
||||
return QVariant(icon.pixmap(16, 16));
|
||||
}
|
||||
bool hasMemo = false;
|
||||
for (int i=0; i < dat.items.length(); i++) {
|
||||
if (!dat.items[i].memo.isEmpty()) {
|
||||
hasMemo = true;
|
||||
}
|
||||
}
|
||||
|
||||
// If the memo is a Payment URI, then show a payment request icon
|
||||
if (dat.items.length() == 1 && dat.items[0].memo.startsWith("zcash:")) {
|
||||
QIcon icon(":/icons/res/paymentreq.gif");
|
||||
return QVariant(icon.pixmap(16, 16));
|
||||
} else if (hasMemo) {
|
||||
// Return the info pixmap to indicate memo
|
||||
QIcon icon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxInformation);
|
||||
return QVariant(icon.pixmap(16, 16));
|
||||
} else {
|
||||
// Empty pixmap to make it align
|
||||
QPixmap p(16, 16);
|
||||
@@ -208,7 +196,21 @@ QString TxTableModel::getTxId(int row) const {
|
||||
}
|
||||
|
||||
QString TxTableModel::getMemo(int row) const {
|
||||
return modeldata->at(row).memo;
|
||||
auto dat = modeldata->at(row);
|
||||
bool hasMemo = false;
|
||||
for (int i=0; i < dat.items.length(); i++) {
|
||||
if (!dat.items[i].memo.isEmpty()) {
|
||||
hasMemo = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (dat.items.length() == 1) {
|
||||
return dat.items[0].memo;
|
||||
} else if (hasMemo) {
|
||||
return "(Multiple)";
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
qint64 TxTableModel::getConfirmations(int row) const {
|
||||
@@ -228,5 +230,11 @@ QString TxTableModel::getType(int row) const {
|
||||
}
|
||||
|
||||
QString TxTableModel::getAmt(int row) const {
|
||||
return Settings::getDecimalString(modeldata->at(row).amount);
|
||||
auto dat = modeldata->at(row);
|
||||
|
||||
qint64 total = 0;
|
||||
for (int i=0; i < dat.items.length(); i++) {
|
||||
total += dat.items[i].amount;
|
||||
}
|
||||
return Settings::getDecimalString(total);
|
||||
}
|
||||
|
||||
@@ -20,9 +20,7 @@ public:
|
||||
Amount = 4
|
||||
};
|
||||
|
||||
void addTData (const QList<TransactionItem>& data);
|
||||
void addZSentData(const QList<TransactionItem>& data);
|
||||
void addZRecvData(const QList<TransactionItem>& data);
|
||||
void replaceData (const QList<TransactionItem>& data);
|
||||
|
||||
QString getTxId(int row) const;
|
||||
QString getMemo(int row) const;
|
||||
@@ -40,12 +38,6 @@ public:
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
|
||||
|
||||
private:
|
||||
void updateAllData();
|
||||
|
||||
QList<TransactionItem>* tTrans = nullptr;
|
||||
QList<TransactionItem>* zrTrans = nullptr; // Z received
|
||||
QList<TransactionItem>* zsTrans = nullptr; // Z sent
|
||||
|
||||
QList<TransactionItem>* modeldata = nullptr;
|
||||
|
||||
QList<QString> headers;
|
||||
|
||||
@@ -44,7 +44,6 @@ SOURCES += \
|
||||
src/3rdparty/qrcode/QrSegment.cpp \
|
||||
src/settings.cpp \
|
||||
src/sendtab.cpp \
|
||||
src/senttxstore.cpp \
|
||||
src/txtablemodel.cpp \
|
||||
src/qrcodelabel.cpp \
|
||||
src/connection.cpp \
|
||||
@@ -73,7 +72,6 @@ HEADERS += \
|
||||
src/3rdparty/json/json.hpp \
|
||||
src/settings.h \
|
||||
src/txtablemodel.h \
|
||||
src/senttxstore.h \
|
||||
src/qrcodelabel.h \
|
||||
src/connection.h \
|
||||
src/fillediconlabel.h \
|
||||
|
||||
Reference in New Issue
Block a user