diff --git a/src/balancestablemodel.cpp b/src/balancestablemodel.cpp index 28261d2..12bcf09 100644 --- a/src/balancestablemodel.cpp +++ b/src/balancestablemodel.cpp @@ -7,8 +7,8 @@ BalancesTableModel::BalancesTableModel(QObject *parent) : QAbstractTableModel(parent) { } -void BalancesTableModel::setNewData(const QMap* balances, - const QList* outputs) +void BalancesTableModel::setNewData(const QMap balances, + const QList outputs) { loading = false; @@ -16,15 +16,16 @@ void BalancesTableModel::setNewData(const QMap* balances, // Copy over the utxos for our use delete utxos; utxos = new QList(); + // This is a QList deep copy. - *utxos = *outputs; + *utxos = outputs; // Process the address balances into a list delete modeldata; modeldata = new QList>(); - 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 diff --git a/src/balancestablemodel.h b/src/balancestablemodel.h index 3ad3550..45e2c52 100644 --- a/src/balancestablemodel.h +++ b/src/balancestablemodel.h @@ -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* balances, const QList* outputs); + void setNewData(const QMap balances, const QList outputs); int rowCount(const QModelIndex &parent) const; int columnCount(const QModelIndex &parent) const; diff --git a/src/controller.cpp b/src/controller.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/controller.h b/src/controller.h new file mode 100644 index 0000000..e69de29 diff --git a/src/datamodel.cpp b/src/datamodel.cpp new file mode 100644 index 0000000..975ad8d --- /dev/null +++ b/src/datamodel.cpp @@ -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(); + balances = new QMap(); + usedAddresses = new QMap(); + zaddresses = new QList(); + taddresses = new QList(); +} + +DataModel::~DataModel() { + delete lock; + + delete utxos; + delete balances; + delete usedAddresses; + delete zaddresses; + delete taddresses; +} + +void DataModel::replaceZaddresses(QList* newZ) { + QWriteLocker locker(lock); + Q_ASSERT(newZ); + + delete zaddresses; + zaddresses = newZ; +} + + +void DataModel::replaceTaddresses(QList* newT) { + QWriteLocker locker(lock); + Q_ASSERT(newT); + + delete taddresses; + taddresses = newT; +} + +void DataModel::replaceBalances(QMap* newBalances) { + QWriteLocker locker(lock); + Q_ASSERT(newBalances); + + delete balances; + balances = newBalances; +} + + +void DataModel::replaceUTXOs(QList* newutxos) { + QWriteLocker locker(lock); + Q_ASSERT(newutxos); + + delete utxos; + utxos = newutxos; +} + +void DataModel::markAddressUsed(QString address) { + QWriteLocker locker(lock); + + usedAddresses->insert(address, true); +} \ No newline at end of file diff --git a/src/datamodel.h b/src/datamodel.h new file mode 100644 index 0000000..bd91b74 --- /dev/null +++ b/src/datamodel.h @@ -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* newZ); + void replaceTaddresses(QList* newZ); + void replaceBalances(QMap* newBalances); + void replaceUTXOs(QList* utxos); + + void markAddressUsed(QString address); + + const QList getAllZAddresses() { QReadLocker locker(lock); return *zaddresses; } + const QList getAllTAddresses() { QReadLocker locker(lock); return *taddresses; } + const QList getUTXOs() { QReadLocker locker(lock); return *utxos; } + const QMap getAllBalances() { QReadLocker locker(lock); return *balances; } + const QMap getUsedAddresses() { QReadLocker locker(lock); return *usedAddresses; } + + + DataModel(); + ~DataModel(); +private: + + + QList* utxos = nullptr; + QMap* balances = nullptr; + QMap* usedAddresses = nullptr; + QList* zaddresses = nullptr; + QList* taddresses = nullptr; + + QReadWriteLock* lock; + +}; + +#endif // DATAMODEL_H \ No newline at end of file diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 6f2e492..dfcf6df 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -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 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 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 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 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(ui->listReceiveAddresses->model()); diff --git a/src/requestdialog.cpp b/src/requestdialog.cpp index 6c8e74c..f3fa12e 100644 --- a/src/requestdialog.cpp +++ b/src/requestdialog.cpp @@ -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); } diff --git a/src/rpc.cpp b/src/rpc.cpp index 7c9b9ce..66632c6 100644 --- a/src/rpc.cpp +++ b/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(); + // 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 emptyBalances; QList emptyOutputs; - balancesTableModel->setNewData(&emptyBalances, &emptyOutputs); + balancesTableModel->setNewData(emptyBalances, emptyOutputs); // Clear Transactions table. QList emptyTxs; @@ -462,7 +459,7 @@ void RPC::refreshReceivedZTrans(QList zaddrs) { auto zaddr = it.key(); for (auto& i : it.value().get()) { // Mark the address as used - usedAddresses->insert(zaddr, true); + model->markAddressUsed(zaddr); // Filter out change txs if (! i["change"].get()) { @@ -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)> 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(); } diff --git a/src/rpc.h b/src/rpc.h index a6474fe..da3086f 100644 --- a/src/rpc.h +++ b/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* getAllZAddresses() { return zaddresses; } - const QList* getAllTAddresses() { return taddresses; } - const QList* getUTXOs() { return utxos; } - const QMap* getAllBalances() { return allBalances; } - const QMap* getUsedAddresses() { return usedAddresses; } void newZaddr(bool sapling, const std::function& cb); void newTaddr(const std::function& cb); @@ -127,17 +127,13 @@ private: Connection* conn = nullptr; QProcess* ezcashd = nullptr; - QList* utxos = nullptr; - QMap* allBalances = nullptr; - QMap* usedAddresses = nullptr; - QList* zaddresses = nullptr; - QList* taddresses = nullptr; - QMap watchingOps; TxTableModel* transactionsTableModel = nullptr; BalancesTableModel* balancesTableModel = nullptr; + DataModel* model; + QTimer* timer; QTimer* txTimer; QTimer* priceTimer; diff --git a/src/sendtab.cpp b/src/sendtab.cpp index 7487d60..db583ad 100644 --- a/src/sendtab.cpp +++ b/src/sendtab.cpp @@ -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 diff --git a/src/turnstile.cpp b/src/turnstile.cpp index f7625dc..727b5fa 100644 --- a/src/turnstile.cpp +++ b/src/turnstile.cpp @@ -84,7 +84,7 @@ QList 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) { diff --git a/src/viewalladdresses.cpp b/src/viewalladdresses.cpp index 7b7af7d..de00926 100644 --- a/src/viewalladdresses.cpp +++ b/src/viewalladdresses.cpp @@ -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(); diff --git a/src/websockets.cpp b/src/websockets.cpp index f5c6bde..c102658 100644 --- a/src/websockets.cpp +++ b/src/websockets.cpp @@ -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> 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(i, allBalances->value(i))); + bals.append(QPair(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 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); } } diff --git a/zec-qt-wallet.pro b/zec-qt-wallet.pro index 756eea2..35fbcd0 100644 --- a/zec-qt-wallet.pro +++ b/zec-qt-wallet.pro @@ -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 \