Add DataModel class
This commit is contained in:
@@ -7,8 +7,8 @@ BalancesTableModel::BalancesTableModel(QObject *parent)
|
||||
: QAbstractTableModel(parent) {
|
||||
}
|
||||
|
||||
void BalancesTableModel::setNewData(const QMap<QString, double>* balances,
|
||||
const QList<UnspentOutput>* outputs)
|
||||
void BalancesTableModel::setNewData(const QMap<QString, double> balances,
|
||||
const QList<UnspentOutput> outputs)
|
||||
{
|
||||
loading = false;
|
||||
|
||||
@@ -16,15 +16,16 @@ void BalancesTableModel::setNewData(const QMap<QString, double>* balances,
|
||||
// Copy over the utxos for our use
|
||||
delete utxos;
|
||||
utxos = new QList<UnspentOutput>();
|
||||
|
||||
// This is a QList deep copy.
|
||||
*utxos = *outputs;
|
||||
*utxos = outputs;
|
||||
|
||||
// Process the address balances into a list
|
||||
delete modeldata;
|
||||
modeldata = new QList<std::tuple<QString, double>>();
|
||||
std::for_each(balances->keyBegin(), balances->keyEnd(), [=] (auto keyIt) {
|
||||
if (balances->value(keyIt) > 0)
|
||||
modeldata->push_back(std::make_tuple(keyIt, balances->value(keyIt)));
|
||||
std::for_each(balances.keyBegin(), balances.keyEnd(), [=] (auto keyIt) {
|
||||
if (balances.value(keyIt) > 0)
|
||||
modeldata->push_back(std::make_tuple(keyIt, balances.value(keyIt)));
|
||||
});
|
||||
|
||||
// And then update the data
|
||||
|
||||
@@ -2,14 +2,7 @@
|
||||
#define BALANCESTABLEMODEL_H
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
struct UnspentOutput {
|
||||
QString address;
|
||||
QString txid;
|
||||
QString amount;
|
||||
int confirmations;
|
||||
bool spendable;
|
||||
};
|
||||
#include "datamodel.h"
|
||||
|
||||
class BalancesTableModel : public QAbstractTableModel
|
||||
{
|
||||
@@ -17,7 +10,7 @@ public:
|
||||
BalancesTableModel(QObject* parent);
|
||||
~BalancesTableModel();
|
||||
|
||||
void setNewData(const QMap<QString, double>* balances, const QList<UnspentOutput>* outputs);
|
||||
void setNewData(const QMap<QString, double> balances, const QList<UnspentOutput> outputs);
|
||||
|
||||
int rowCount(const QModelIndex &parent) const;
|
||||
int columnCount(const QModelIndex &parent) const;
|
||||
|
||||
0
src/controller.cpp
Normal file
0
src/controller.cpp
Normal file
0
src/controller.h
Normal file
0
src/controller.h
Normal file
64
src/datamodel.cpp
Normal file
64
src/datamodel.cpp
Normal file
@@ -0,0 +1,64 @@
|
||||
#include "datamodel.h"
|
||||
|
||||
DataModel::DataModel() {
|
||||
lock = new QReadWriteLock();
|
||||
|
||||
// Write lock because we're creating everything
|
||||
QWriteLocker locker(lock);
|
||||
|
||||
utxos = new QList<UnspentOutput>();
|
||||
balances = new QMap<QString, double>();
|
||||
usedAddresses = new QMap<QString, bool>();
|
||||
zaddresses = new QList<QString>();
|
||||
taddresses = new QList<QString>();
|
||||
}
|
||||
|
||||
DataModel::~DataModel() {
|
||||
delete lock;
|
||||
|
||||
delete utxos;
|
||||
delete balances;
|
||||
delete usedAddresses;
|
||||
delete zaddresses;
|
||||
delete taddresses;
|
||||
}
|
||||
|
||||
void DataModel::replaceZaddresses(QList<QString>* newZ) {
|
||||
QWriteLocker locker(lock);
|
||||
Q_ASSERT(newZ);
|
||||
|
||||
delete zaddresses;
|
||||
zaddresses = newZ;
|
||||
}
|
||||
|
||||
|
||||
void DataModel::replaceTaddresses(QList<QString>* newT) {
|
||||
QWriteLocker locker(lock);
|
||||
Q_ASSERT(newT);
|
||||
|
||||
delete taddresses;
|
||||
taddresses = newT;
|
||||
}
|
||||
|
||||
void DataModel::replaceBalances(QMap<QString, double>* newBalances) {
|
||||
QWriteLocker locker(lock);
|
||||
Q_ASSERT(newBalances);
|
||||
|
||||
delete balances;
|
||||
balances = newBalances;
|
||||
}
|
||||
|
||||
|
||||
void DataModel::replaceUTXOs(QList<UnspentOutput>* newutxos) {
|
||||
QWriteLocker locker(lock);
|
||||
Q_ASSERT(newutxos);
|
||||
|
||||
delete utxos;
|
||||
utxos = newutxos;
|
||||
}
|
||||
|
||||
void DataModel::markAddressUsed(QString address) {
|
||||
QWriteLocker locker(lock);
|
||||
|
||||
usedAddresses->insert(address, true);
|
||||
}
|
||||
48
src/datamodel.h
Normal file
48
src/datamodel.h
Normal file
@@ -0,0 +1,48 @@
|
||||
#ifndef DATAMODEL_H
|
||||
#define DATAMODEL_H
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
|
||||
struct UnspentOutput {
|
||||
QString address;
|
||||
QString txid;
|
||||
QString amount;
|
||||
int confirmations;
|
||||
bool spendable;
|
||||
};
|
||||
|
||||
|
||||
// Data class that holds all the data about the wallet.
|
||||
class DataModel {
|
||||
public:
|
||||
void replaceZaddresses(QList<QString>* newZ);
|
||||
void replaceTaddresses(QList<QString>* newZ);
|
||||
void replaceBalances(QMap<QString, double>* newBalances);
|
||||
void replaceUTXOs(QList<UnspentOutput>* utxos);
|
||||
|
||||
void markAddressUsed(QString address);
|
||||
|
||||
const QList<QString> getAllZAddresses() { QReadLocker locker(lock); return *zaddresses; }
|
||||
const QList<QString> getAllTAddresses() { QReadLocker locker(lock); return *taddresses; }
|
||||
const QList<UnspentOutput> getUTXOs() { QReadLocker locker(lock); return *utxos; }
|
||||
const QMap<QString, double> getAllBalances() { QReadLocker locker(lock); return *balances; }
|
||||
const QMap<QString, bool> getUsedAddresses() { QReadLocker locker(lock); return *usedAddresses; }
|
||||
|
||||
|
||||
DataModel();
|
||||
~DataModel();
|
||||
private:
|
||||
|
||||
|
||||
QList<UnspentOutput>* utxos = nullptr;
|
||||
QMap<QString, double>* balances = nullptr;
|
||||
QMap<QString, bool>* usedAddresses = nullptr;
|
||||
QList<QString>* zaddresses = nullptr;
|
||||
QList<QString>* taddresses = nullptr;
|
||||
|
||||
QReadWriteLock* lock;
|
||||
|
||||
};
|
||||
|
||||
#endif // DATAMODEL_H
|
||||
@@ -302,12 +302,6 @@ void MainWindow::turnstileProgress() {
|
||||
}
|
||||
|
||||
void MainWindow::turnstileDoMigration(QString fromAddr) {
|
||||
// Return if there is no connection
|
||||
if (rpc->getAllZAddresses() == nullptr || rpc->getAllBalances() == nullptr) {
|
||||
QMessageBox::information(this, tr("Not yet ready"), tr("zcashd is not yet ready. Please wait for the UI to load"), QMessageBox::Ok);
|
||||
return;
|
||||
}
|
||||
|
||||
// If a migration is already in progress, show the progress dialog instead
|
||||
if (rpc->getTurnstile()->isMigrationPresent()) {
|
||||
turnstileProgress();
|
||||
@@ -324,9 +318,9 @@ void MainWindow::turnstileDoMigration(QString fromAddr) {
|
||||
|
||||
auto fnGetAllSproutBalance = [=] () {
|
||||
double bal = 0;
|
||||
for (auto addr : *rpc->getAllZAddresses()) {
|
||||
if (Settings::getInstance()->isSproutAddress(addr) && rpc->getAllBalances()) {
|
||||
bal += rpc->getAllBalances()->value(addr);
|
||||
for (auto addr : rpc->getModel()->getAllZAddresses()) {
|
||||
if (Settings::getInstance()->isSproutAddress(addr)) {
|
||||
bal += rpc->getModel()->getAllBalances().value(addr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -334,8 +328,8 @@ void MainWindow::turnstileDoMigration(QString fromAddr) {
|
||||
};
|
||||
|
||||
turnstile.fromBalance->setText(Settings::getZECUSDDisplayFormat(fnGetAllSproutBalance()));
|
||||
for (auto addr : *rpc->getAllZAddresses()) {
|
||||
auto bal = rpc->getAllBalances()->value(addr);
|
||||
for (auto addr : rpc->getModel()->getAllZAddresses()) {
|
||||
auto bal = rpc->getModel()->getAllBalances().value(addr);
|
||||
if (Settings::getInstance()->isSaplingAddress(addr)) {
|
||||
turnstile.migrateTo->addItem(addr, bal);
|
||||
} else {
|
||||
@@ -354,7 +348,7 @@ void MainWindow::turnstileDoMigration(QString fromAddr) {
|
||||
if (addr.startsWith("All")) {
|
||||
bal = fnGetAllSproutBalance();
|
||||
} else {
|
||||
bal = rpc->getAllBalances()->value(addr);
|
||||
bal = rpc->getModel()->getAllBalances().value(addr);
|
||||
}
|
||||
|
||||
auto balTxt = Settings::getZECUSDDisplayFormat(bal);
|
||||
@@ -734,8 +728,8 @@ void MainWindow::postToZBoard() {
|
||||
return;
|
||||
|
||||
// Fill the from field with sapling addresses.
|
||||
for (auto i = rpc->getAllBalances()->keyBegin(); i != rpc->getAllBalances()->keyEnd(); i++) {
|
||||
if (Settings::getInstance()->isSaplingAddress(*i) && rpc->getAllBalances()->value(*i) > 0) {
|
||||
for (auto i = rpc->getModel()->getAllBalances().keyBegin(); i != rpc->getModel()->getAllBalances().keyEnd(); i++) {
|
||||
if (Settings::getInstance()->isSaplingAddress(*i) && rpc->getModel()->getAllBalances().value(*i) > 0) {
|
||||
zb.fromAddr->addItem(*i);
|
||||
}
|
||||
}
|
||||
@@ -1331,20 +1325,18 @@ void MainWindow::addNewZaddr(bool sapling) {
|
||||
// lambda, which can be connected to the appropriate signal
|
||||
std::function<void(bool)> MainWindow::addZAddrsToComboList(bool sapling) {
|
||||
return [=] (bool checked) {
|
||||
if (checked && this->rpc->getAllZAddresses() != nullptr) {
|
||||
auto addrs = this->rpc->getAllZAddresses();
|
||||
if (checked) {
|
||||
auto addrs = this->rpc->getModel()->getAllZAddresses();
|
||||
|
||||
// Save the current address, so we can update it later
|
||||
auto zaddr = ui->listReceiveAddresses->currentText();
|
||||
ui->listReceiveAddresses->clear();
|
||||
|
||||
std::for_each(addrs->begin(), addrs->end(), [=] (auto addr) {
|
||||
std::for_each(addrs.begin(), addrs.end(), [=] (auto addr) {
|
||||
if ( (sapling && Settings::getInstance()->isSaplingAddress(addr)) ||
|
||||
(!sapling && !Settings::getInstance()->isSaplingAddress(addr))) {
|
||||
if (rpc->getAllBalances()) {
|
||||
auto bal = rpc->getAllBalances()->value(addr);
|
||||
ui->listReceiveAddresses->addItem(addr, bal);
|
||||
}
|
||||
(!sapling && !Settings::getInstance()->isSaplingAddress(addr))) {
|
||||
auto bal = rpc->getModel()->getAllBalances().value(addr);
|
||||
ui->listReceiveAddresses->addItem(addr, bal);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1353,7 +1345,7 @@ std::function<void(bool)> MainWindow::addZAddrsToComboList(bool sapling) {
|
||||
}
|
||||
|
||||
// If z-addrs are empty, then create a new one.
|
||||
if (addrs->isEmpty()) {
|
||||
if (addrs.isEmpty()) {
|
||||
addNewZaddr(sapling);
|
||||
}
|
||||
}
|
||||
@@ -1381,7 +1373,7 @@ void MainWindow::setupReceiveTab() {
|
||||
QObject::connect(ui->rdioTAddr, &QRadioButton::toggled, [=] (bool checked) {
|
||||
// Whenever the t-address is selected, we generate a new address, because we don't
|
||||
// want to reuse t-addrs
|
||||
if (checked && this->rpc->getUTXOs() != nullptr) {
|
||||
if (checked) {
|
||||
updateTAddrCombo(checked);
|
||||
}
|
||||
|
||||
@@ -1402,7 +1394,7 @@ void MainWindow::setupReceiveTab() {
|
||||
Settings::saveRestoreTableHeader(viewaddrs.tblAddresses, &d, "viewalladdressestable");
|
||||
viewaddrs.tblAddresses->horizontalHeader()->setStretchLastSection(true);
|
||||
|
||||
ViewAllAddressesModel model(viewaddrs.tblAddresses, *getRPC()->getAllTAddresses(), getRPC());
|
||||
ViewAllAddressesModel model(viewaddrs.tblAddresses, getRPC()->getModel()->getAllTAddresses(), getRPC());
|
||||
viewaddrs.tblAddresses->setModel(&model);
|
||||
|
||||
QObject::connect(viewaddrs.btnExportAll, &QPushButton::clicked, this, &MainWindow::exportAllKeys);
|
||||
@@ -1484,10 +1476,10 @@ void MainWindow::setupReceiveTab() {
|
||||
}
|
||||
|
||||
ui->rcvLabel->setText(label);
|
||||
ui->rcvBal->setText(Settings::getZECUSDDisplayFormat(rpc->getAllBalances()->value(addr)));
|
||||
ui->rcvBal->setText(Settings::getZECUSDDisplayFormat(rpc->getModel()->getAllBalances().value(addr)));
|
||||
ui->txtReceive->setPlainText(addr);
|
||||
ui->qrcodeDisplay->setQrcodeString(addr);
|
||||
if (rpc->getUsedAddresses()->value(addr, false)) {
|
||||
if (rpc->getModel()->getUsedAddresses().value(addr, false)) {
|
||||
ui->rcvBal->setToolTip(tr("Address has been previously used"));
|
||||
} else {
|
||||
ui->rcvBal->setToolTip(tr("Address is unused"));
|
||||
@@ -1543,7 +1535,7 @@ void MainWindow::setupReceiveTab() {
|
||||
|
||||
void MainWindow::updateTAddrCombo(bool checked) {
|
||||
if (checked) {
|
||||
auto utxos = this->rpc->getUTXOs();
|
||||
auto utxos = this->rpc->getModel()->getUTXOs();
|
||||
|
||||
// Save the current address so we can restore it later
|
||||
auto currentTaddr = ui->listReceiveAddresses->currentText();
|
||||
@@ -1555,10 +1547,10 @@ void MainWindow::updateTAddrCombo(bool checked) {
|
||||
QSet<QString> addrs;
|
||||
|
||||
// 1. Add all t addresses that have a balance
|
||||
std::for_each(utxos->begin(), utxos->end(), [=, &addrs](auto& utxo) {
|
||||
std::for_each(utxos.begin(), utxos.end(), [=, &addrs](auto& utxo) {
|
||||
auto addr = utxo.address;
|
||||
if (Settings::isTAddress(addr) && !addrs.contains(addr)) {
|
||||
auto bal = rpc->getAllBalances()->value(addr);
|
||||
auto bal = rpc->getModel()->getAllBalances().value(addr);
|
||||
ui->listReceiveAddresses->addItem(addr, bal);
|
||||
|
||||
addrs.insert(addr);
|
||||
@@ -1566,12 +1558,12 @@ void MainWindow::updateTAddrCombo(bool checked) {
|
||||
});
|
||||
|
||||
// 2. Add all t addresses that have a label
|
||||
auto allTaddrs = this->rpc->getAllTAddresses();
|
||||
auto allTaddrs = this->rpc->getModel()->getAllTAddresses();
|
||||
QSet<QString> labels;
|
||||
for (auto p : AddressBook::getInstance()->getAllAddressLabels()) {
|
||||
labels.insert(p.second);
|
||||
}
|
||||
std::for_each(allTaddrs->begin(), allTaddrs->end(), [=, &addrs] (auto& taddr) {
|
||||
std::for_each(allTaddrs.begin(), allTaddrs.end(), [=, &addrs] (auto& taddr) {
|
||||
// If the address is in the address book, add it.
|
||||
if (labels.contains(taddr) && !addrs.contains(taddr)) {
|
||||
addrs.insert(taddr);
|
||||
@@ -1581,8 +1573,8 @@ void MainWindow::updateTAddrCombo(bool checked) {
|
||||
|
||||
// 3. Add all t-addresses. We won't add more than 20 total t-addresses,
|
||||
// since it will overwhelm the dropdown
|
||||
for (int i=0; addrs.size() < 20 && i < allTaddrs->size(); i++) {
|
||||
auto addr = allTaddrs->at(i);
|
||||
for (int i=0; addrs.size() < 20 && i < allTaddrs.size(); i++) {
|
||||
auto addr = allTaddrs.at(i);
|
||||
if (!addrs.contains(addr)) {
|
||||
addrs.insert(addr);
|
||||
// Balance is zero since it has not been previously added
|
||||
@@ -1594,15 +1586,15 @@ void MainWindow::updateTAddrCombo(bool checked) {
|
||||
if (!currentTaddr.isEmpty() && Settings::isTAddress(currentTaddr)) {
|
||||
// Make sure the current taddr is in the list
|
||||
if (!addrs.contains(currentTaddr)) {
|
||||
auto bal = rpc->getAllBalances()->value(currentTaddr);
|
||||
auto bal = rpc->getModel()->getAllBalances().value(currentTaddr);
|
||||
ui->listReceiveAddresses->addItem(currentTaddr, bal);
|
||||
}
|
||||
ui->listReceiveAddresses->setCurrentText(currentTaddr);
|
||||
}
|
||||
|
||||
// 5. Add a last, disabled item if there are remaining items
|
||||
if (allTaddrs->size() > addrs.size()) {
|
||||
auto num = QString::number(allTaddrs->size() - addrs.size());
|
||||
if (allTaddrs.size() > addrs.size()) {
|
||||
auto num = QString::number(allTaddrs.size() - addrs.size());
|
||||
ui->listReceiveAddresses->addItem("-- " + num + " more --", 0);
|
||||
|
||||
QStandardItemModel* model = qobject_cast<QStandardItemModel*>(ui->listReceiveAddresses->model());
|
||||
|
||||
@@ -28,11 +28,11 @@ void RequestDialog::setupDialog(MainWindow* main, QDialog* d, Ui_RequestDialog*
|
||||
req->txtMemo->setLenDisplayLabel(req->lblMemoLen);
|
||||
req->lblAmount->setText(req->lblAmount->text() + Settings::getTokenName());
|
||||
|
||||
if (!main || !main->getRPC() || !main->getRPC()->getAllZAddresses() || !main->getRPC()->getAllBalances())
|
||||
if (!main || !main->getRPC())
|
||||
return;
|
||||
|
||||
for (auto addr : *main->getRPC()->getAllZAddresses()) {
|
||||
auto bal = main->getRPC()->getAllBalances()->value(addr);
|
||||
for (auto addr : main->getRPC()->getModel()->getAllZAddresses()) {
|
||||
auto bal = main->getRPC()->getModel()->getAllBalances().value(addr);
|
||||
if (Settings::getInstance()->isSaplingAddress(addr)) {
|
||||
req->cmbMyAddress->addItem(addr, bal);
|
||||
}
|
||||
|
||||
38
src/rpc.cpp
38
src/rpc.cpp
@@ -51,7 +51,8 @@ RPC::RPC(MainWindow* main) {
|
||||
// Start at every 10s. When an operation is pending, this will change to every second
|
||||
txTimer->start(Settings::updateSpeed);
|
||||
|
||||
usedAddresses = new QMap<QString, bool>();
|
||||
// Create the data model
|
||||
model = new DataModel();
|
||||
|
||||
// Initialize the migration status to unavailable.
|
||||
this->migrationStatus.available = false;
|
||||
@@ -65,11 +66,7 @@ RPC::~RPC() {
|
||||
delete balancesTableModel;
|
||||
delete turnstile;
|
||||
|
||||
delete utxos;
|
||||
delete allBalances;
|
||||
delete usedAddresses;
|
||||
delete zaddresses;
|
||||
delete taddresses;
|
||||
delete model;
|
||||
|
||||
delete conn;
|
||||
}
|
||||
@@ -403,7 +400,7 @@ void RPC::noConnection() {
|
||||
// Clear balances table.
|
||||
QMap<QString, double> emptyBalances;
|
||||
QList<UnspentOutput> emptyOutputs;
|
||||
balancesTableModel->setNewData(&emptyBalances, &emptyOutputs);
|
||||
balancesTableModel->setNewData(emptyBalances, emptyOutputs);
|
||||
|
||||
// Clear Transactions table.
|
||||
QList<TransactionItem> emptyTxs;
|
||||
@@ -462,7 +459,7 @@ void RPC::refreshReceivedZTrans(QList<QString> zaddrs) {
|
||||
auto zaddr = it.key();
|
||||
for (auto& i : it.value().get<json::array_t>()) {
|
||||
// Mark the address as used
|
||||
usedAddresses->insert(zaddr, true);
|
||||
model->markAddressUsed(zaddr);
|
||||
|
||||
// Filter out change txs
|
||||
if (! i["change"].get<json::boolean_t>()) {
|
||||
@@ -721,12 +718,11 @@ void RPC::refreshAddresses() {
|
||||
newzaddresses->push_back(addr);
|
||||
}
|
||||
|
||||
delete zaddresses;
|
||||
zaddresses = newzaddresses;
|
||||
model->replaceZaddresses(newzaddresses);
|
||||
|
||||
// Refresh the sent and received txs from all these z-addresses
|
||||
refreshSentZTrans();
|
||||
refreshReceivedZTrans(*zaddresses);
|
||||
refreshReceivedZTrans(model->getAllZAddresses());
|
||||
});
|
||||
|
||||
|
||||
@@ -738,8 +734,7 @@ void RPC::refreshAddresses() {
|
||||
newtaddresses->push_back(addr);
|
||||
}
|
||||
|
||||
delete taddresses;
|
||||
taddresses = newtaddresses;
|
||||
model->replaceTaddresses(newtaddresses);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -748,7 +743,7 @@ void RPC::updateUI(bool anyUnconfirmed) {
|
||||
ui->unconfirmedWarning->setVisible(anyUnconfirmed);
|
||||
|
||||
// Update balances model data, which will update the table too
|
||||
balancesTableModel->setNewData(allBalances, utxos);
|
||||
balancesTableModel->setNewData(model->getAllBalances(), model->getUTXOs());
|
||||
|
||||
// Update from address
|
||||
main->updateFromCombo();
|
||||
@@ -853,11 +848,8 @@ void RPC::refreshBalances() {
|
||||
auto anyZUnconfirmed = processUnspent(reply, newBalances, newUtxos);
|
||||
|
||||
// Swap out the balances and UTXOs
|
||||
delete allBalances;
|
||||
delete utxos;
|
||||
|
||||
allBalances = newBalances;
|
||||
utxos = newUtxos;
|
||||
model->replaceBalances(newBalances);
|
||||
model->replaceUTXOs(newUtxos);
|
||||
|
||||
updateUI(anyTUnconfirmed || anyZUnconfirmed);
|
||||
|
||||
@@ -892,7 +884,7 @@ void RPC::refreshTransactions() {
|
||||
|
||||
txdata.push_back(tx);
|
||||
if (!address.isEmpty())
|
||||
usedAddresses->insert(address, true);
|
||||
model->markAddressUsed(address);
|
||||
}
|
||||
|
||||
// Update model data, which updates the table view
|
||||
@@ -1304,7 +1296,7 @@ void RPC::getZboardTopics(std::function<void(QMap<QString, QString>)> cb) {
|
||||
* Get a Sapling address from the user's wallet
|
||||
*/
|
||||
QString RPC::getDefaultSaplingAddress() {
|
||||
for (QString addr: *zaddresses) {
|
||||
for (QString addr: model->getAllZAddresses()) {
|
||||
if (Settings::getInstance()->isSaplingAddress(addr))
|
||||
return addr;
|
||||
}
|
||||
@@ -1313,8 +1305,8 @@ QString RPC::getDefaultSaplingAddress() {
|
||||
}
|
||||
|
||||
QString RPC::getDefaultTAddress() {
|
||||
if (getAllTAddresses()->length() > 0)
|
||||
return getAllTAddresses()->at(0);
|
||||
if (model->getAllTAddresses().length() > 0)
|
||||
return model->getAllTAddresses().at(0);
|
||||
else
|
||||
return QString();
|
||||
}
|
||||
|
||||
18
src/rpc.h
18
src/rpc.h
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
#include "datamodel.h"
|
||||
#include "balancestablemodel.h"
|
||||
#include "txtablemodel.h"
|
||||
#include "ui_mainwindow.h"
|
||||
@@ -46,6 +47,8 @@ public:
|
||||
RPC(MainWindow* main);
|
||||
~RPC();
|
||||
|
||||
DataModel* getModel() { return model; }
|
||||
|
||||
void setConnection(Connection* c);
|
||||
void setEZcashd(QProcess* p);
|
||||
const QProcess* getEZcashD() { return ezcashd; }
|
||||
@@ -53,6 +56,8 @@ public:
|
||||
void refresh(bool force = false);
|
||||
|
||||
void refreshAddresses();
|
||||
|
||||
|
||||
|
||||
void checkForUpdate(bool silent = true);
|
||||
void refreshZECPrice();
|
||||
@@ -73,11 +78,6 @@ public:
|
||||
void addNewTxToWatch(const QString& newOpid, WatchedTx wtx);
|
||||
|
||||
const TxTableModel* getTransactionsModel() { return transactionsTableModel; }
|
||||
const QList<QString>* getAllZAddresses() { return zaddresses; }
|
||||
const QList<QString>* getAllTAddresses() { return taddresses; }
|
||||
const QList<UnspentOutput>* getUTXOs() { return utxos; }
|
||||
const QMap<QString, double>* getAllBalances() { return allBalances; }
|
||||
const QMap<QString, bool>* getUsedAddresses() { return usedAddresses; }
|
||||
|
||||
void newZaddr(bool sapling, const std::function<void(json)>& cb);
|
||||
void newTaddr(const std::function<void(json)>& cb);
|
||||
@@ -127,17 +127,13 @@ private:
|
||||
Connection* conn = nullptr;
|
||||
QProcess* ezcashd = nullptr;
|
||||
|
||||
QList<UnspentOutput>* utxos = nullptr;
|
||||
QMap<QString, double>* allBalances = nullptr;
|
||||
QMap<QString, bool>* usedAddresses = nullptr;
|
||||
QList<QString>* zaddresses = nullptr;
|
||||
QList<QString>* taddresses = nullptr;
|
||||
|
||||
QMap<QString, WatchedTx> watchingOps;
|
||||
|
||||
TxTableModel* transactionsTableModel = nullptr;
|
||||
BalancesTableModel* balancesTableModel = nullptr;
|
||||
|
||||
DataModel* model;
|
||||
|
||||
QTimer* timer;
|
||||
QTimer* txTimer;
|
||||
QTimer* priceTimer;
|
||||
|
||||
@@ -175,7 +175,7 @@ void MainWindow::setDefaultPayFrom() {
|
||||
for (int i=0; i < ui->inputsCombo->count(); i++) {
|
||||
auto addr = ui->inputsCombo->itemText(i);
|
||||
if (addr.startsWith(startsWith)) {
|
||||
auto amt = rpc->getAllBalances()->value(addr);
|
||||
auto amt = rpc->getModel()->getAllBalances().value(addr);
|
||||
if (max_amt < amt) {
|
||||
max_amt = amt;
|
||||
idx = i;
|
||||
@@ -198,16 +198,16 @@ void MainWindow::setDefaultPayFrom() {
|
||||
};
|
||||
|
||||
void MainWindow::updateFromCombo() {
|
||||
if (!rpc || !rpc->getAllBalances())
|
||||
if (!rpc)
|
||||
return;
|
||||
|
||||
auto lastFromAddr = ui->inputsCombo->currentText();
|
||||
|
||||
ui->inputsCombo->clear();
|
||||
auto i = rpc->getAllBalances()->constBegin();
|
||||
auto i = rpc->getModel()->getAllBalances().constBegin();
|
||||
|
||||
// Add all the addresses into the inputs combo box
|
||||
while (i != rpc->getAllBalances()->constEnd()) {
|
||||
while (i != rpc->getModel()->getAllBalances().constEnd()) {
|
||||
ui->inputsCombo->addItem(i.key(), i.value());
|
||||
if (i.key() == lastFromAddr) ui->inputsCombo->setCurrentText(i.key());
|
||||
|
||||
@@ -224,7 +224,7 @@ void MainWindow::updateFromCombo() {
|
||||
|
||||
void MainWindow::inputComboTextChanged(int index) {
|
||||
auto addr = ui->inputsCombo->itemText(index);
|
||||
auto bal = rpc->getAllBalances()->value(addr);
|
||||
auto bal = rpc->getModel()->getAllBalances().value(addr);
|
||||
auto balFmt = Settings::getZECDisplayFormat(bal);
|
||||
|
||||
ui->sendAddressBalance->setText(balFmt);
|
||||
@@ -459,7 +459,7 @@ void MainWindow::clearSendForm() {
|
||||
void MainWindow::maxAmountChecked(int checked) {
|
||||
if (checked == Qt::Checked) {
|
||||
ui->Amount1->setReadOnly(true);
|
||||
if (rpc->getAllBalances() == nullptr) return;
|
||||
if (rpc == nullptr) return;
|
||||
|
||||
// Calculate maximum amount
|
||||
double sumAllAmounts = 0.0;
|
||||
@@ -481,7 +481,7 @@ void MainWindow::maxAmountChecked(int checked) {
|
||||
|
||||
auto addr = ui->inputsCombo->currentText();
|
||||
|
||||
auto maxamount = rpc->getAllBalances()->value(addr) - sumAllAmounts;
|
||||
auto maxamount = rpc->getModel()->getAllBalances().value(addr) - sumAllAmounts;
|
||||
maxamount = (maxamount < 0) ? 0 : maxamount;
|
||||
|
||||
ui->Amount1->setText(Settings::getDecimalString(maxamount));
|
||||
@@ -531,7 +531,7 @@ Tx MainWindow::createTxFromSendPage() {
|
||||
}
|
||||
|
||||
if (Settings::getInstance()->getAutoShield() && sendChangeToSapling) {
|
||||
auto saplingAddr = std::find_if(rpc->getAllZAddresses()->begin(), rpc->getAllZAddresses()->end(), [=](auto i) -> bool {
|
||||
auto saplingAddr = std::find_if(rpc->getModel()->getAllZAddresses().begin(), rpc->getModel()->getAllZAddresses().end(), [=](auto i) -> bool {
|
||||
// We're finding a sapling address that is not one of the To addresses, because zcash doesn't allow duplicated addresses
|
||||
bool isSapling = Settings::getInstance()->isSaplingAddress(i);
|
||||
if (!isSapling) return false;
|
||||
@@ -545,8 +545,8 @@ Tx MainWindow::createTxFromSendPage() {
|
||||
return true;
|
||||
});
|
||||
|
||||
if (saplingAddr != rpc->getAllZAddresses()->end()) {
|
||||
double change = rpc->getAllBalances()->value(tx.fromAddr) - totalAmt - tx.fee;
|
||||
if (saplingAddr != rpc->getModel()->getAllZAddresses().end()) {
|
||||
double change = rpc->getModel()->getAllBalances().value(tx.fromAddr) - totalAmt - tx.fee;
|
||||
|
||||
if (Settings::getDecimalString(change) != "0") {
|
||||
QString changeMemo = tr("Change from ") + tx.fromAddr;
|
||||
@@ -724,9 +724,9 @@ bool MainWindow::confirmTx(Tx tx, RecurringPaymentInfo* rpi) {
|
||||
confirm.sendFrom->setText(fnSplitAddressForWrap(tx.fromAddr));
|
||||
confirm.sendFrom->setFont(fixedFont);
|
||||
QString tooltip = tr("Current balance : ") +
|
||||
Settings::getZECUSDDisplayFormat(rpc->getAllBalances()->value(tx.fromAddr));
|
||||
Settings::getZECUSDDisplayFormat(rpc->getModel()->getAllBalances().value(tx.fromAddr));
|
||||
tooltip += "\n" + tr("Balance after this Tx: ") +
|
||||
Settings::getZECUSDDisplayFormat(rpc->getAllBalances()->value(tx.fromAddr) - totalSpending);
|
||||
Settings::getZECUSDDisplayFormat(rpc->getModel()->getAllBalances().value(tx.fromAddr) - totalSpending);
|
||||
confirm.sendFrom->setToolTip(tooltip);
|
||||
|
||||
// Show the dialog and submit it if the user confirms
|
||||
|
||||
@@ -84,7 +84,7 @@ QList<TurnstileMigrationItem> Turnstile::readMigrationPlan() {
|
||||
|
||||
void Turnstile::planMigration(QString zaddr, QString destAddr, int numsplits, int numBlocks) {
|
||||
// First, get the balance and split up the amounts
|
||||
auto bal = rpc->getAllBalances()->value(zaddr);
|
||||
auto bal = rpc->getModel()->getAllBalances().value(zaddr);
|
||||
auto splits = splitAmount(bal, numsplits);
|
||||
|
||||
// Then, generate an intermediate t-address for each part using getBatchRPC
|
||||
@@ -266,10 +266,10 @@ void Turnstile::executeMigrationStep() {
|
||||
|
||||
// Fn to find if there are any unconfirmed funds for this address.
|
||||
auto fnHasUnconfirmed = [=] (QString addr) {
|
||||
auto utxoset = rpc->getUTXOs();
|
||||
return std::find_if(utxoset->begin(), utxoset->end(), [=] (auto utxo) {
|
||||
auto utxoset = rpc->getModel()->getUTXOs();
|
||||
return std::find_if(utxoset.begin(), utxoset.end(), [=] (auto utxo) {
|
||||
return utxo.address == addr && utxo.confirmations == 0 && utxo.spendable;
|
||||
}) != utxoset->end();
|
||||
}) != utxoset.end();
|
||||
};
|
||||
|
||||
// Find the next step
|
||||
@@ -292,7 +292,7 @@ void Turnstile::executeMigrationStep() {
|
||||
return;
|
||||
}
|
||||
|
||||
auto balance = rpc->getAllBalances()->value(nextStep->fromAddr);
|
||||
auto balance = rpc->getModel()->getAllBalances().value(nextStep->fromAddr);
|
||||
if (nextStep->amount > balance) {
|
||||
qDebug() << "Not enough balance!";
|
||||
nextStep->status = TurnstileMigrationItemStatus::NotEnoughBalance;
|
||||
@@ -329,13 +329,13 @@ void Turnstile::executeMigrationStep() {
|
||||
|
||||
// Sometimes, we check too quickly, and the unspent UTXO is not updated yet, so we'll
|
||||
// double check to see if there is enough balance.
|
||||
if (!rpc->getAllBalances()->keys().contains(nextStep->intTAddr)) {
|
||||
if (!rpc->getModel()->getAllBalances().keys().contains(nextStep->intTAddr)) {
|
||||
//qDebug() << QString("The intermediate t-address doesn't have balance, even though it seems to be confirmed");
|
||||
return;
|
||||
}
|
||||
|
||||
// Send it to the final destination address.
|
||||
auto bal = rpc->getAllBalances()->value(nextStep->intTAddr);
|
||||
auto bal = rpc->getModel()->getAllBalances().value(nextStep->intTAddr);
|
||||
auto sendAmt = bal - Settings::getMinerFee();
|
||||
|
||||
if (sendAmt < 0) {
|
||||
|
||||
@@ -22,7 +22,7 @@ QVariant ViewAllAddressesModel::data(const QModelIndex &index, int role) const {
|
||||
if (role == Qt::DisplayRole) {
|
||||
switch(index.column()) {
|
||||
case 0: return address;
|
||||
case 1: return rpc->getAllBalances()->value(address, 0.0);
|
||||
case 1: return rpc->getModel()->getAllBalances().value(address, 0.0);
|
||||
}
|
||||
}
|
||||
return QVariant();
|
||||
|
||||
@@ -659,17 +659,17 @@ void AppDataServer::processSendTx(QJsonObject sendTx, MainWindow* mainwindow, st
|
||||
|
||||
// Find a from address that has at least the sending amout
|
||||
double amt = sendTx["amount"].toString().toDouble();
|
||||
auto allBalances = mainwindow->getRPC()->getAllBalances();
|
||||
auto allBalances = mainwindow->getRPC()->getModel()->getAllBalances();
|
||||
QList<QPair<QString, double>> bals;
|
||||
for (auto i : allBalances->keys()) {
|
||||
for (auto i : allBalances.keys()) {
|
||||
// Filter out sprout addresses
|
||||
if (Settings::getInstance()->isSproutAddress(i))
|
||||
continue;
|
||||
// Filter out balances that don't have the requisite amount
|
||||
if (allBalances->value(i) < amt)
|
||||
if (allBalances.value(i) < amt)
|
||||
continue;
|
||||
|
||||
bals.append(QPair<QString, double>(i, allBalances->value(i)));
|
||||
bals.append(QPair<QString, double>(i, allBalances.value(i)));
|
||||
}
|
||||
|
||||
if (bals.isEmpty()) {
|
||||
@@ -732,24 +732,22 @@ void AppDataServer::processSendTx(QJsonObject sendTx, MainWindow* mainwindow, st
|
||||
void AppDataServer::processGetInfo(QJsonObject jobj, MainWindow* mainWindow, std::shared_ptr<ClientWebSocket> pClient) {
|
||||
auto connectedName = jobj["name"].toString();
|
||||
|
||||
if (mainWindow == nullptr || mainWindow->getRPC() == nullptr ||
|
||||
mainWindow->getRPC()->getAllBalances() == nullptr) {
|
||||
if (mainWindow == nullptr || mainWindow->getRPC() == nullptr) {
|
||||
pClient->close(QWebSocketProtocol::CloseCodeNormal, "Not yet ready");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Max spendable safely from a z address and from any address
|
||||
double maxZSpendable = 0;
|
||||
double maxSpendable = 0;
|
||||
for (auto a : mainWindow->getRPC()->getAllBalances()->keys()) {
|
||||
for (auto a : mainWindow->getRPC()->getModel()->getAllBalances().keys()) {
|
||||
if (Settings::getInstance()->isSaplingAddress(a)) {
|
||||
if (mainWindow->getRPC()->getAllBalances()->value(a) > maxZSpendable) {
|
||||
maxZSpendable = mainWindow->getRPC()->getAllBalances()->value(a);
|
||||
if (mainWindow->getRPC()->getModel()->getAllBalances().value(a) > maxZSpendable) {
|
||||
maxZSpendable = mainWindow->getRPC()->getModel()->getAllBalances().value(a);
|
||||
}
|
||||
}
|
||||
if (mainWindow->getRPC()->getAllBalances()->value(a) > maxSpendable) {
|
||||
maxSpendable = mainWindow->getRPC()->getAllBalances()->value(a);
|
||||
if (mainWindow->getRPC()->getModel()->getAllBalances().value(a) > maxSpendable) {
|
||||
maxSpendable = mainWindow->getRPC()->getModel()->getAllBalances().value(a);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +60,9 @@ SOURCES += \
|
||||
src/recurring.cpp \
|
||||
src/requestdialog.cpp \
|
||||
src/memoedit.cpp \
|
||||
src/viewalladdresses.cpp
|
||||
src/viewalladdresses.cpp \
|
||||
src/datamodel.cpp \
|
||||
src/controller.cpp
|
||||
|
||||
HEADERS += \
|
||||
src/mainwindow.h \
|
||||
@@ -87,7 +89,9 @@ HEADERS += \
|
||||
src/recurring.h \
|
||||
src/requestdialog.h \
|
||||
src/memoedit.h \
|
||||
src/viewalladdresses.h
|
||||
src/viewalladdresses.h \
|
||||
src/datamodel.h \
|
||||
src/controller.h
|
||||
|
||||
FORMS += \
|
||||
src/mainwindow.ui \
|
||||
|
||||
Reference in New Issue
Block a user