]> Nutra Git (v2) - gamesguru/feather.git/commitdiff
Coins: cleanup
authortobtoht <tob@featherwallet.org>
Tue, 11 Mar 2025 20:45:38 +0000 (21:45 +0100)
committertobtoht <tob@featherwallet.org>
Tue, 11 Mar 2025 20:45:38 +0000 (21:45 +0100)
12 files changed:
src/CoinsWidget.cpp
src/CoinsWidget.h
src/MainWindow.cpp
src/dialog/OutputInfoDialog.cpp
src/dialog/OutputInfoDialog.h
src/libwalletqt/Coins.cpp
src/libwalletqt/Coins.h
src/libwalletqt/rows/CoinsInfo.cpp
src/libwalletqt/rows/CoinsInfo.h
src/model/CoinsModel.cpp
src/model/CoinsModel.h
src/model/CoinsProxyModel.cpp

index 1df731033e203e49bbb289285f10c03b4293a90d..c955575ef1290a6f3337aa8b6a2564027c1902e7 100644 (file)
@@ -121,12 +121,15 @@ void CoinsWidget::showContextMenu(const QPoint &point) {
         menu->addAction(m_sweepOutputsAction);
     }
     else {
-        CoinsInfo* c = this->currentEntry();
-        if (!c) return;
+        auto index = this->getCurrentIndex();
+        if (!index.isValid()) {
+            return;
+        }
+        const CoinsInfo& c = m_model->entryFromIndex(index);
 
-        bool isSpent = c->spent();
-        bool isFrozen = c->frozen();
-        bool isUnlocked = c->unlocked();
+        bool isSpent = c.spent;
+        bool isFrozen = c.frozen;
+        bool isUnlocked = c.unlocked;
 
         menu->addAction(m_spendAction);
         menu->addMenu(m_copyMenu);
@@ -170,7 +173,7 @@ QStringList CoinsWidget::selectedPubkeys() {
 
     QStringList pubkeys;
     for (QModelIndex index: list) {
-        pubkeys << m_model->entryFromIndex(m_proxyModel->mapToSource(index))->pubKey();
+        pubkeys << m_model->entryFromIndex(m_proxyModel->mapToSource(index)).pubKey;
     }
     return pubkeys;
 }
@@ -186,16 +189,19 @@ void CoinsWidget::thawAllSelected() {
 }
 
 void CoinsWidget::spendSelected() {
-    QVector<CoinsInfo*> selectedCoins = this->currentEntries();
-    QStringList keyimages;
+    QModelIndexList selectedRows = ui->coins->selectionModel()->selectedRows();
 
-    for (const auto coin : selectedCoins) {
-        if (!coin) return;
+    QStringList keyimages;
+    for (const auto index : selectedRows) {
+        if (!index.isValid()) {
+            return;
+        }
+        const CoinsInfo& coin = m_model->entryFromIndex(m_proxyModel->mapToSource(index));
 
         bool spendable = this->isCoinSpendable(coin);
         if (!spendable) return;
 
-        QString keyImage = coin->keyImage();
+        QString keyImage = coin.keyImage;
         keyimages << keyImage;
     }
 
@@ -204,8 +210,11 @@ void CoinsWidget::spendSelected() {
 }
 
 void CoinsWidget::viewOutput() {
-    CoinsInfo* c = this->currentEntry();
-    if (!c) return;
+    auto index = this->getCurrentIndex();
+    if (!index.isValid()) {
+        return;
+    }
+    const CoinsInfo& c = m_model->entryFromIndex(index);
 
     auto * dialog = new OutputInfoDialog(c, this);
     dialog->show();
@@ -224,19 +233,23 @@ void CoinsWidget::onSweepOutputs() {
         return;
     }
 
-    QVector<CoinsInfo*> selectedCoins = this->currentEntries();
+    QModelIndexList selectedRows = ui->coins->selectionModel()->selectedRows();
+
     QVector<QString> keyImages;
 
     quint64 totalAmount = 0;
-    for (const auto coin : selectedCoins) {
-        if (!coin) return;
+    for (const auto index : selectedRows) {
+        if (!index.isValid()) {
+            return;
+        }
+        const CoinsInfo& coin = m_model->entryFromIndex(m_proxyModel->mapToSource(index));
 
         bool spendable = this->isCoinSpendable(coin);
         if (!spendable) return;
 
-        QString keyImage = coin->keyImage();
+        QString keyImage = coin.keyImage;
         keyImages.push_back(keyImage);
-        totalAmount += coin->amount();
+        totalAmount += coin.amount;
     }
 
     OutputSweepDialog dialog{this, totalAmount};
@@ -270,59 +283,44 @@ void CoinsWidget::onSweepOutputs() {
 }
 
 void CoinsWidget::copy(copyField field) {
-    CoinsInfo* c = this->currentEntry();
-    if (!c) return;
+    auto index = this->getCurrentIndex();
+    if (!index.isValid()) {
+        return;
+    }
+    const CoinsInfo& c = m_model->entryFromIndex(index);
 
     QString data;
     switch (field) {
         case PubKey:
-            data = c->pubKey();
+            data = c.pubKey;
             break;
         case KeyImage:
-            data = c->keyImage();
+            data = c.keyImage;
             break;
         case TxID:
-            data = c->hash();
+            data = c.hash;
             break;
         case Address:
-            data = c->address();
+            data = c.address;
             break;
         case Label: {
-            if (!c->description().isEmpty())
-                data = c->description();
+            if (!c.description.isEmpty())
+                data = c.description;
             else
-                data = c->addressLabel();
+                data = c.getAddressLabel();
             break;
         }
         case Height:
-            data = QString::number(c->blockHeight());
+            data = QString::number(c.blockHeight);
             break;
         case Amount:
-            data = c->displayAmount();
+            data = c.displayAmount();
             break;
     }
 
     Utils::copyToClipboard(data);
 }
 
-CoinsInfo* CoinsWidget::currentEntry() {
-    QModelIndexList list = ui->coins->selectionModel()->selectedRows();
-    if (list.size() == 1) {
-        return m_model->entryFromIndex(m_proxyModel->mapToSource(list.first()));
-    } else {
-        return nullptr;
-    }
-}
-
-QVector<CoinsInfo*> CoinsWidget::currentEntries() {
-    QModelIndexList list = ui->coins->selectionModel()->selectedRows();
-    QVector<CoinsInfo*> selectedCoins;
-    for (const auto index : list) {
-        selectedCoins.push_back(m_model->entryFromIndex(m_proxyModel->mapToSource(index)));
-    }
-    return selectedCoins;
-}
-
 void CoinsWidget::freezeCoins(QStringList &pubkeys) {
     m_wallet->coins()->freeze(pubkeys);
     m_wallet->updateBalance();
@@ -344,23 +342,23 @@ void CoinsWidget::editLabel() {
     ui->coins->edit(index);
 }
 
-bool CoinsWidget::isCoinSpendable(CoinsInfo *coin) {
-    if (!coin->keyImageKnown()) {
+bool CoinsWidget::isCoinSpendable(const CoinsInfo &coin) {
+    if (!coin.keyImageKnown) {
         Utils::showError(this, "Unable to spend outputs", "Selected output has unknown key image");
         return false;
     }
 
-    if (coin->spent()) {
+    if (coin.spent) {
         Utils::showError(this, "Unable to spend outputs", "Selected output was already spent");
         return false;
     }
 
-    if (coin->frozen()) {
+    if (coin.frozen) {
         Utils::showError(this, "Unable to spend outputs", "Selected output is frozen", {"Thaw the selected output(s) before spending"}, "freeze_thaw_outputs");
         return false;
     }
 
-    if (!coin->unlocked()) {
+    if (!coin.unlocked) {
         Utils::showError(this, "Unable to spend outputs", "Selected output is locked", {"Wait until the output has reached the required number of confirmation before spending."});
         return false;
     }
@@ -368,4 +366,14 @@ bool CoinsWidget::isCoinSpendable(CoinsInfo *coin) {
     return true;
 }
 
+QModelIndex CoinsWidget::getCurrentIndex()
+{
+    QModelIndexList list = ui->coins->selectionModel()->selectedRows();
+    if (list.length() < 1) {
+        return {};
+    }
+
+    return m_proxyModel->mapToSource(list.first());
+}
+
 CoinsWidget::~CoinsWidget() = default;
\ No newline at end of file
index f3ddcb5f228ef7bedf720e680f0e2d42c5c70e93..5ca8bc5cc593b3a67851083141350681b8082afc 100644 (file)
@@ -83,10 +83,9 @@ private:
 
     void showContextMenu(const QPoint & point);
     void copy(copyField field);
-    CoinsInfo* currentEntry();
-    QVector<CoinsInfo*> currentEntries();
     QStringList selectedPubkeys();
-    bool isCoinSpendable(CoinsInfo* coin);
+    bool isCoinSpendable(const CoinsInfo& coin);
+    QModelIndex getCurrentIndex();
 };
 
 
index bac74d4680c651f6a371cfbc1a54cbf164c1e36e..8ac436bcf591adcd561d93fd8fbf3c3baa5525de 100644 (file)
@@ -1673,11 +1673,7 @@ void MainWindow::onSelectedInputsChanged(const QStringList &selectedInputs) {
     ui->frame_coinControl->setVisible(numInputs > 0);
 
     if (numInputs > 0) {
-        quint64 totalAmount = 0;
-        auto coins = m_wallet->coins()->coinsFromKeyImage(selectedInputs);
-        for (const auto coin : coins) {
-            totalAmount += coin->amount();
-        }
+        quint64 totalAmount = m_wallet->coins()->sumAmounts(selectedInputs);
 
         QString text = QString("Coin control active: %1 selected outputs, %2 XMR").arg(QString::number(numInputs), WalletManager::displayAmount(totalAmount));
         ui->label_coinControl->setText(text);
index e78ef2c8ed191d5acf20b6bf6b7a7151ee22e009..8f7ceb636fb557460c1df770942492f527116b08 100644 (file)
@@ -6,7 +6,7 @@
 
 #include "utils/Utils.h"
 
-OutputInfoDialog::OutputInfoDialog(CoinsInfo *cInfo, QWidget *parent)
+OutputInfoDialog::OutputInfoDialog(const CoinsInfo &cInfo, QWidget *parent)
         : WindowModalDialog(parent)
         , ui(new Ui::OutputInfoDialog)
 {
@@ -18,19 +18,19 @@ OutputInfoDialog::OutputInfoDialog(CoinsInfo *cInfo, QWidget *parent)
     ui->label_txid->setFont(font);
     ui->label_address->setFont(font);
 
-    ui->label_pubKey->setText(cInfo->pubKey());
-    ui->label_keyImage->setText(cInfo->keyImage());
-    ui->label_txid->setText(cInfo->hash());
-    ui->label_address->setText(cInfo->address());
+    ui->label_pubKey->setText(cInfo.pubKey);
+    ui->label_keyImage->setText(cInfo.keyImage);
+    ui->label_txid->setText(cInfo.hash);
+    ui->label_address->setText(cInfo.address);
 
-    QString status = cInfo->spent() ? "spent" : (cInfo->frozen() ? "frozen" : "unspent");
+    QString status = cInfo.spent ? "spent" : (cInfo.frozen ? "frozen" : "unspent");
     ui->label_status->setText(status);
-    ui->label_amount->setText(QString("%1 XMR").arg(cInfo->displayAmount()));
-    ui->label_creationHeight->setText(QString::number(cInfo->blockHeight()));
-    ui->label_globalIndex->setText(QString::number(cInfo->globalOutputIndex()));
-    ui->label_internalIndex->setText(QString::number(cInfo->internalOutputIndex()));
+    ui->label_amount->setText(QString("%1 XMR").arg(cInfo.displayAmount()));
+    ui->label_creationHeight->setText(QString::number(cInfo.blockHeight));
+    ui->label_globalIndex->setText(QString::number(cInfo.globalOutputIndex));
+    ui->label_internalIndex->setText(QString::number(cInfo.internalOutputIndex));
 
-    QString spentHeight = QVariant(cInfo->spentHeight()).toString();
+    QString spentHeight = QVariant(cInfo.spentHeight).toString();
     if (spentHeight == "0") spentHeight = "n/a";
     ui->label_spentHeight->setText(spentHeight);
 
index 0a6cdf5c965090b93a51bf4f0682c6209b7fec21..1bc310681addf966f3902d6b3d23154529d62c08 100644 (file)
@@ -19,12 +19,11 @@ class OutputInfoDialog : public WindowModalDialog
 Q_OBJECT
 
 public:
-    explicit OutputInfoDialog(CoinsInfo *cInfo, QWidget *parent = nullptr);
+    explicit OutputInfoDialog(const CoinsInfo &cInfo, QWidget *parent = nullptr);
     ~OutputInfoDialog() override;
 
 private:
     QScopedPointer<Ui::OutputInfoDialog> ui;
 };
 
-
 #endif //FEATHER_OUTPUTINFODIALOG_H
index ef0b7c84ca3aa1a486d6eee23d2ee6d950921939..5ffbaab531895641d7492ce2b606532c4e1f4a63 100644 (file)
@@ -13,23 +13,17 @@ Coins::Coins(Wallet *wallet, tools::wallet2 *wallet2, QObject *parent)
 
 }
 
-bool Coins::coin(int index, std::function<void (CoinsInfo &)> callback)
+const QList<CoinsInfo>& Coins::getRows()
 {
-    QReadLocker locker(&m_lock);
-
-    if (index < 0 || index >= m_rows.size()) {
-        qCritical("%s: no transaction info for index %d", __FUNCTION__, index);
-        qCritical("%s: there's %lld transactions in backend", __FUNCTION__, m_rows.count());
-        return false;
-    }
-
-    callback(*m_rows.value(index));
-    return true;
+    return m_rows;
 }
 
-CoinsInfo* Coins::coin(int index)
+const CoinsInfo& Coins::getRow(const qsizetype i)
 {
-    return m_rows.value(index);
+    if (i < 0 || i >= m_rows.size()) {
+        throw std::out_of_range("Index out of range");
+    }
+    return m_rows[i];
 }
 
 void Coins::refresh()
@@ -54,30 +48,30 @@ void Coins::refresh()
                 continue;
             }
 
-            auto ci = new CoinsInfo(this);
-            ci->m_blockHeight = td.m_block_height;
-            ci->m_hash = QString::fromStdString(epee::string_tools::pod_to_hex(td.m_txid));
-            ci->m_internalOutputIndex = td.m_internal_output_index;
-            ci->m_globalOutputIndex = td.m_global_output_index;
-            ci->m_spent = td.m_spent;
-            ci->m_frozen = td.m_frozen;
-            ci->m_spentHeight = td.m_spent_height;
-            ci->m_amount = td.m_amount;
-            ci->m_rct = td.m_rct;
-            ci->m_keyImageKnown = td.m_key_image_known;
-            ci->m_pkIndex = td.m_pk_index;
-            ci->m_subaddrIndex = td.m_subaddr_index.minor;
-            ci->m_subaddrAccount = td.m_subaddr_index.major;
-            ci->m_address = QString::fromStdString(m_wallet2->get_subaddress_as_str(td.m_subaddr_index)); // todo: this is expensive, cache maybe?
-            ci->m_addressLabel = QString::fromStdString(m_wallet2->get_subaddress_label(td.m_subaddr_index));
-            ci->m_txNote = QString::fromStdString(m_wallet2->get_tx_note(td.m_txid));
-            ci->m_keyImage = QString::fromStdString(epee::string_tools::pod_to_hex(td.m_key_image));
-            ci->m_unlockTime = td.m_tx.unlock_time;
-            ci->m_unlocked = m_wallet2->is_transfer_unlocked(td);
-            ci->m_pubKey = QString::fromStdString(epee::string_tools::pod_to_hex(td.get_public_key()));
-            ci->m_coinbase = td.m_tx.vin.size() == 1 && td.m_tx.vin[0].type() == typeid(cryptonote::txin_gen);
-            ci->m_description = m_wallet->getCacheAttribute(QString("coin.description:%1").arg(ci->m_pubKey));
-            ci->m_change = m_wallet2->is_change(td);
+            CoinsInfo ci;
+            ci.blockHeight = td.m_block_height;
+            ci.hash = QString::fromStdString(epee::string_tools::pod_to_hex(td.m_txid));
+            ci.internalOutputIndex = td.m_internal_output_index;
+            ci.globalOutputIndex = td.m_global_output_index;
+            ci.spent = td.m_spent;
+            ci.frozen = td.m_frozen;
+            ci.spentHeight = td.m_spent_height;
+            ci.amount = td.m_amount;
+            ci.rct = td.m_rct;
+            ci.keyImageKnown = td.m_key_image_known;
+            ci.pkIndex = td.m_pk_index;
+            ci.subaddrIndex = td.m_subaddr_index.minor;
+            ci.subaddrAccount = td.m_subaddr_index.major;
+            ci.address = QString::fromStdString(m_wallet2->get_subaddress_as_str(td.m_subaddr_index)); // todo: this is expensive, cache maybe?
+            ci.addressLabel = QString::fromStdString(m_wallet2->get_subaddress_label(td.m_subaddr_index));
+            ci.txNote = QString::fromStdString(m_wallet2->get_tx_note(td.m_txid));
+            ci.keyImage = QString::fromStdString(epee::string_tools::pod_to_hex(td.m_key_image));
+            ci.unlockTime = td.m_tx.unlock_time;
+            ci.unlocked = m_wallet2->is_transfer_unlocked(td);
+            ci.pubKey = QString::fromStdString(epee::string_tools::pod_to_hex(td.get_public_key()));
+            ci.coinbase = td.m_tx.vin.size() == 1 && td.m_tx.vin[0].type() == typeid(cryptonote::txin_gen);
+            ci.description = m_wallet->getCacheAttribute(QString("coin.description:%1").arg(ci.pubKey));
+            ci.change = m_wallet2->is_change(td);
 
             m_rows.push_back(ci);
         }
@@ -90,10 +84,10 @@ void Coins::refreshUnlocked()
 {
     QWriteLocker locker(&m_lock);
 
-    for (CoinsInfo* c : m_rows) {
-        if (!c->unlocked()) {
-            bool unlocked = m_wallet2->is_transfer_unlocked(c->unlockTime(), c->blockHeight());
-            c->setUnlocked(unlocked);
+    for (CoinsInfo& c : m_rows) {
+        if (!c.unlocked) {
+            bool unlocked = m_wallet2->is_transfer_unlocked(c.unlockTime, c.blockHeight);
+            c.setUnlocked(unlocked);
         }
     }
 }
@@ -153,30 +147,21 @@ void Coins::thaw(QStringList &publicKeys)
     refresh();
 }
 
-QVector<CoinsInfo*> Coins::coins_from_txid(const QString &txid)
-{
-    QVector<CoinsInfo*> coins;
-
-    for (int i = 0; i < this->count(); i++) {
-        CoinsInfo* coin = this->coin(i);
-        if (coin->hash() == txid) {
-            coins.append(coin);
+quint64 Coins::sumAmounts(const QStringList &keyImages) {
+    quint64 amount = 0;
+    for (const CoinsInfo& coin : m_rows) {
+        if (!coin.keyImageKnown) {
+            continue;
         }
-    }
-    return coins;
-}
-
-QVector<CoinsInfo*> Coins::coinsFromKeyImage(const QStringList &keyimages) {
-    QVector<CoinsInfo*> coins;
 
-    for (int i = 0; i < this->count(); i++) {
-        CoinsInfo* coin = this->coin(i);
-        if (coin->keyImageKnown() && keyimages.contains(coin->keyImage())) {
-            coins.append(coin);
+        if (!keyImages.contains(coin.keyImage)) {
+            continue;
         }
+
+        amount += coin.amount;
     }
 
-    return coins;
+    return amount;
 }
 
 void Coins::setDescription(const QString &publicKey, quint32 accountIndex, const QString &description)
@@ -187,6 +172,5 @@ void Coins::setDescription(const QString &publicKey, quint32 accountIndex, const
 }
 
 void Coins::clearRows() {
-    qDeleteAll(m_rows);
     m_rows.clear();
-}
\ No newline at end of file
+}
index eadf92c6a7b0b9d2cc840ddf3e61c883084aa4bc..a967c47b4a77eea4c71c6ef1841244da4c53672f 100644 (file)
@@ -4,8 +4,6 @@
 #ifndef FEATHER_COINS_H
 #define FEATHER_COINS_H
 
-#include <functional>
-
 #include <QObject>
 #include <QList>
 #include <QReadWriteLock>
@@ -27,16 +25,17 @@ class Coins : public QObject
 Q_OBJECT
 
 public:
-    bool coin(int index, std::function<void (CoinsInfo &)> callback);
-    CoinsInfo * coin(int index);
+    const QList<CoinsInfo>& getRows();
+    const CoinsInfo& getRow(qsizetype i);
+
     void refresh();
     void refreshUnlocked();
 
     void freeze(QStringList &publicKeys);
     void thaw(QStringList &publicKeys);
 
-    QVector<CoinsInfo*> coins_from_txid(const QString &txid);
-    QVector<CoinsInfo*> coinsFromKeyImage(const QStringList &keyimages);
+    quint64 sumAmounts(const QStringList &keyImages);
+
     void setDescription(const QString &publicKey, quint32 accountIndex, const QString &description);
 
     quint64 count() const;
@@ -55,7 +54,7 @@ private:
 
     Wallet *m_wallet;
     tools::wallet2 *m_wallet2;
-    QList<CoinsInfo*> m_rows;
+    QList<CoinsInfo> m_rows;
 
     mutable QReadWriteLock m_lock;
 };
index 2c12b5c69c80c5dee9e719362a0e17ac957616d6..2f7dba92a4f0c0e6218a36ff6016630894a19308 100644 (file)
 #include "CoinsInfo.h"
 #include "libwalletqt/WalletManager.h"
 
-quint64 CoinsInfo::blockHeight() const
-{
-    return m_blockHeight;
-}
-
-QString CoinsInfo::hash() const
-{
-    return m_hash;
-}
-
-quint64 CoinsInfo::internalOutputIndex() const
-{
-    return m_internalOutputIndex;
-}
-
-quint64 CoinsInfo::globalOutputIndex() const
-{
-    return m_globalOutputIndex;
-}
-
-bool CoinsInfo::spent() const
-{
-    return m_spent;
-}
-
-bool CoinsInfo::frozen() const
-{
-    return m_frozen;
-}
-
-quint64 CoinsInfo::spentHeight() const
-{
-    return m_spentHeight;
-}
-
-quint64 CoinsInfo::amount() const {
-    return m_amount;
-}
-
 QString CoinsInfo::displayAmount() const
 {
-    return WalletManager::displayAmount(m_amount);
-}
-
-bool CoinsInfo::rct() const {
-    return m_rct;
+    return WalletManager::displayAmount(amount);
 }
 
-bool CoinsInfo::keyImageKnown() const {
-    return m_keyImageKnown;
-}
-
-quint64 CoinsInfo::pkIndex() const {
-    return m_pkIndex;
-}
-
-quint32 CoinsInfo::subaddrIndex() const {
-    return m_subaddrIndex;
-}
-
-quint32 CoinsInfo::subaddrAccount() const {
-    return m_subaddrAccount;
-}
-
-QString CoinsInfo::address() const {
-    return m_address;
-}
-
-QString CoinsInfo::addressLabel() const {
-    if (m_subaddrIndex == 0) {
-        if (m_coinbase) {
+QString CoinsInfo::getAddressLabel() const {
+    if (subaddrIndex == 0) {
+        if (coinbase) {
             return "Coinbase";
         }
-        if (m_change) {
+        if (change) {
             return "Change";
         }
-        if (m_addressLabel == "Primary account") {
+        if (addressLabel == "Primary account") {
             return "Primary address";
         }
     }
 
-    return m_addressLabel;
+    return addressLabel;
 }
 
-QString CoinsInfo::keyImage() const {
-    return m_keyImage;
-}
-
-quint64 CoinsInfo::unlockTime() const {
-    return m_unlockTime;
-}
-
-bool CoinsInfo::unlocked() const {
-    return m_unlocked;
-}
-
-void CoinsInfo::setUnlocked(bool unlocked) {
-    m_unlocked = unlocked;
-}
-
-QString CoinsInfo::pubKey() const {
-    return m_pubKey;
-}
-
-bool CoinsInfo::coinbase() const {
-    return m_coinbase;
-}
-
-QString CoinsInfo::description() const {
-    return m_description;
-}
-
-bool CoinsInfo::change() const {
-    return m_change;
-}
 
-QString CoinsInfo::txNote() const {
-    return m_txNote;
+void CoinsInfo::setUnlocked(bool unlocked_) {
+    unlocked = unlocked_;
 }
 
-CoinsInfo::CoinsInfo(QObject *parent)
-        : QObject(parent)
-        , m_blockHeight(0)
-        , m_internalOutputIndex(0)
-        , m_globalOutputIndex(0)
-        , m_spent(false)
-        , m_frozen(false)
-        , m_spentHeight(0)
-        , m_amount(0)
-        , m_rct(false)
-        , m_keyImageKnown(false)
-        , m_pkIndex(0)
-        , m_subaddrIndex(0)
-        , m_subaddrAccount(0)
-        , m_unlockTime(0)
-        , m_unlocked(false)
-        , m_coinbase(false)
-        , m_change(false)
+CoinsInfo::CoinsInfo()
+        : blockHeight(0)
+        , internalOutputIndex(0)
+        , globalOutputIndex(0)
+        , spent(false)
+        , frozen(false)
+        , spentHeight(0)
+        , amount(0)
+        , rct(false)
+        , keyImageKnown(false)
+        , pkIndex(0)
+        , subaddrIndex(0)
+        , subaddrAccount(0)
+        , unlockTime(0)
+        , unlocked(false)
+        , coinbase(false)
+        , change(false)
 {
 
 }
index 65f7f883549584e1c8bd48284450c2b320c8de1f..2eeb3fbb6fd7aa0914b3ad16a2c10ecc4023fdee 100644 (file)
@@ -4,73 +4,39 @@
 #ifndef FEATHER_COINSINFO_H
 #define FEATHER_COINSINFO_H
 
-#include <QObject>
-#include <QDateTime>
-#include <QSet>
+#include <QString>
 
-class Coins;
-
-class CoinsInfo : public QObject
+struct CoinsInfo
 {
-Q_OBJECT
-
-public:
-    quint64 blockHeight() const;
-    QString hash() const;
-    quint64 internalOutputIndex() const;
-    quint64 globalOutputIndex() const;
-    bool spent() const;
-    bool frozen() const;
-    quint64 spentHeight() const;
-    quint64 amount() const;
+    quint64 blockHeight;
+    QString hash;
+    quint64 internalOutputIndex;
+    quint64 globalOutputIndex;
+    bool spent;
+    bool frozen;
+    quint64 spentHeight;
+    quint64 amount;
+    bool rct;
+    bool keyImageKnown;
+    quint64 pkIndex;
+    quint32 subaddrIndex;
+    quint32 subaddrAccount;
+    QString address;
+    QString addressLabel;
+    QString keyImage;
+    quint64 unlockTime;
+    bool unlocked;
+    QString pubKey;
+    bool coinbase;
+    QString description;
+    bool change;
+    QString txNote;
+
+    QString getAddressLabel() const;
     QString displayAmount() const;
-    bool rct() const;
-    bool keyImageKnown() const;
-    quint64 pkIndex() const;
-    quint32 subaddrIndex() const;
-    quint32 subaddrAccount() const;
-    QString address() const;
-    QString addressLabel() const;
-    QString keyImage() const;
-    quint64 unlockTime() const;
-    bool unlocked() const;
-    QString pubKey() const;
-    bool coinbase() const;
-    QString description() const;
-    bool change() const;
-    QString txNote() const;
-
     void setUnlocked(bool unlocked);
 
-private:
-    explicit CoinsInfo(QObject *parent);
-
-private:
-    friend class Coins;
-
-    quint64 m_blockHeight;
-    QString m_hash;
-    quint64 m_internalOutputIndex;
-    quint64 m_globalOutputIndex;
-    bool m_spent;
-    bool m_frozen;
-    quint64 m_spentHeight;
-    quint64 m_amount;
-    bool m_rct;
-    bool m_keyImageKnown;
-    quint64 m_pkIndex;
-    quint32 m_subaddrIndex;
-    quint32 m_subaddrAccount;
-    QString m_address;
-    QString m_addressLabel;
-    QString m_keyImage;
-    quint64 m_unlockTime;
-    bool m_unlocked;
-    QString m_pubKey;
-    bool m_coinbase;
-    QString m_description;
-    bool m_change;
-    QString m_txNote;
+    explicit CoinsInfo();
 };
 
 #endif //FEATHER_COINSINFO_H
index b79704006100024efbe2d8be7e7f43208245f037..938316da9acc17f2712bd23f6ba4b00c19b9006e 100644 (file)
@@ -28,10 +28,6 @@ void CoinsModel::endReset(){
     endResetModel();
 }
 
-Coins * CoinsModel::coins() const {
-    return m_coins;
-}
-
 int CoinsModel::rowCount(const QModelIndex &parent) const
 {
     if (parent.isValid()) {
@@ -51,91 +47,81 @@ int CoinsModel::columnCount(const QModelIndex &parent) const
 
 QVariant CoinsModel::data(const QModelIndex &index, int role) const
 {
-    if (!m_coins) {
-        return QVariant();
+    const QList<CoinsInfo>& rows = m_coins->getRows();
+    if (index.row() < 0 || index.row() >= rows.size()) {
+        return {};
     }
+    const CoinsInfo& row = rows[index.row()];
 
-    if (!index.isValid() || index.row() < 0 || static_cast<quint64>(index.row()) >= m_coins->count())
-        return QVariant();
-
-    QVariant result;
+    bool selected = row.keyImageKnown && m_selected.contains(row.keyImage);
 
-    bool found = m_coins->coin(index.row(), [this, &index, &result, &role](const CoinsInfo &cInfo) {
-        bool selected = cInfo.keyImageKnown() && m_selected.contains(cInfo.keyImage());
-
-        if(role == Qt::DisplayRole || role == Qt::EditRole || role == Qt::UserRole) {
-            result = parseTransactionInfo(cInfo, index.column(), role);
+    if(role == Qt::DisplayRole || role == Qt::EditRole || role == Qt::UserRole) {
+        return parseTransactionInfo(row, index.column(), role);
+    }
+    else if (role == Qt::BackgroundRole) {
+        if (row.spent) {
+            return QBrush(ColorScheme::RED.asColor(true));
         }
-        else if (role == Qt::BackgroundRole) {
-            if (cInfo.spent()) {
-                result = QBrush(ColorScheme::RED.asColor(true));
-            }
-            else if (cInfo.frozen()) {
-                result = QBrush(ColorScheme::BLUE.asColor(true));
-            }
-            else if (!cInfo.unlocked()) {
-                result = QBrush(ColorScheme::YELLOW.asColor(true));
-            }
-            else if (selected) {
-                result = QBrush(ColorScheme::GREEN.asColor(true));
-            }
+        if (row.frozen) {
+            return QBrush(ColorScheme::BLUE.asColor(true));
         }
-        else if (role == Qt::TextAlignmentRole) {
-            switch (index.column()) {
-                case Amount:
-                    result = Qt::AlignRight;
-            }
+        if (!row.unlocked) {
+            return QBrush(ColorScheme::YELLOW.asColor(true));
         }
-        else if (role == Qt::DecorationRole) {
-            switch (index.column()) {
-                case KeyImageKnown:
-                {
-                    if (cInfo.keyImageKnown()) {
-                        result = QVariant(icons()->icon("eye1.png"));
-                    }
-                    else {
-                        result = QVariant(icons()->icon("eye_blind.png"));
-                    }
+        if (selected) {
+            return QBrush(ColorScheme::GREEN.asColor(true));
+        }
+    }
+    else if (role == Qt::TextAlignmentRole) {
+        switch (index.column()) {
+            case Amount:
+                return Qt::AlignRight;
+        }
+    }
+    else if (role == Qt::DecorationRole) {
+        switch (index.column()) {
+            case KeyImageKnown:
+            {
+                if (row.keyImageKnown) {
+                    return QVariant(icons()->icon("eye1.png"));
                 }
+                return QVariant(icons()->icon("eye_blind.png"));
             }
         }
-        else if (role == Qt::FontRole) {
-            switch(index.column()) {
-                case PubKey:
-                case TxID:
-                case Address:
-                    result = Utils::getMonospaceFont();
-            }
+    }
+    else if (role == Qt::FontRole) {
+        switch(index.column()) {
+            case PubKey:
+            case TxID:
+            case Address:
+                return Utils::getMonospaceFont();
         }
-        else if (role == Qt::ToolTipRole) {
-            switch(index.column()) {
-                case KeyImageKnown:
-                {
-                    if (cInfo.keyImageKnown()) {
-                        result = "Key image known";
-                    } else {
-                        result = "Key image unknown. Outgoing transactions that include this output will not be detected.";
-                    }
+    }
+    else if (role == Qt::ToolTipRole) {
+        switch(index.column()) {
+            case KeyImageKnown:
+            {
+                if (row.keyImageKnown) {
+                    return "Key image known";
                 }
+                return "Key image unknown. Outgoing transactions that include this output will not be detected.";
             }
-            if (cInfo.frozen()) {
-                result = "Output is frozen.";
-            }
-            else if (!cInfo.unlocked()) {
-                result = "Output is locked (needs more confirmations)";
-            }
-            else if (cInfo.spent()) {
-                result = "Output is spent";
-            }
-            else if (selected) {
-                result = "Coin selected to be spent";
-            }
         }
-    });
-    if (!found) {
-        qCritical("%s: internal error: no transaction info for index %d", __FUNCTION__, index.row());
+        if (row.frozen) {
+            return "Output is frozen.";
+        }
+        if (!row.unlocked) {
+            return "Output is locked (needs more confirmations)";
+        }
+        if (row.spent) {
+            return "Output is spent";
+        }
+        if (selected) {
+            return "Coin selected to be spent";
+        }
     }
-    return result;
+
+    return {};
 }
 
 QVariant CoinsModel::headerData(int section, Qt::Orientation orientation, int role) const
@@ -185,15 +171,9 @@ Qt::ItemFlags CoinsModel::flags(const QModelIndex &index) const
 bool CoinsModel::setData(const QModelIndex &index, const QVariant &value, int role)
 {
     if (index.isValid() && role == Qt::EditRole) {
-        const int row = index.row();
+        const CoinsInfo& row = m_coins->getRow(index.row());
 
-        QString pubkey;
-        bool found = m_coins->coin(index.row(), [this, &pubkey](const CoinsInfo &cInfo) {
-            pubkey = cInfo.pubKey();
-        });
-        if (!found) {
-            return false;
-        }
+        QString pubkey = row.pubKey;
 
         switch (index.column()) {
             case Label:
@@ -218,33 +198,33 @@ QVariant CoinsModel::parseTransactionInfo(const CoinsInfo &cInfo, int column, in
         case KeyImageKnown:
             return "";
         case PubKey:
-            return cInfo.pubKey().mid(0,8);
+            return cInfo.pubKey.mid(0,8);
         case TxID:
-            return cInfo.hash().mid(0, 8) + " ";
+            return cInfo.hash.mid(0, 8) + " ";
         case BlockHeight:
-            return cInfo.blockHeight();
+            return cInfo.blockHeight;
         case Address:
-            return Utils::displayAddress(cInfo.address(), 1, "");
+            return Utils::displayAddress(cInfo.address, 1, "");
         case Label: {
-            if (!cInfo.description().isEmpty())
-                return cInfo.description();
-            if (!cInfo.txNote().isEmpty())
-                return cInfo.txNote();
-            return cInfo.addressLabel();
+            if (!cInfo.description.isEmpty())
+                return cInfo.description;
+            if (!cInfo.txNote.isEmpty())
+                return cInfo.txNote;
+            return cInfo.getAddressLabel();
         }
         case Spent:
-            return cInfo.spent();
+            return cInfo.spent;
         case SpentHeight:
-            return cInfo.spentHeight();
+            return cInfo.spentHeight;
         case Amount:
         {
             if (role == Qt::UserRole) {
-                return cInfo.amount();
+                return cInfo.amount;
             }
             return cInfo.displayAmount();
         }
         case Frozen:
-            return cInfo.frozen();
+            return cInfo.frozen;
         default:
         {
             qCritical() << "Unimplemented role";
@@ -265,7 +245,7 @@ void CoinsModel::setSelected(const QStringList &keyimages) {
     emit dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1));
 }
 
-CoinsInfo* CoinsModel::entryFromIndex(const QModelIndex &index) const {
+const CoinsInfo& CoinsModel::entryFromIndex(const QModelIndex &index) const {
     Q_ASSERT(index.isValid() && index.row() < m_coins->count());
-    return m_coins->coin(index.row());
-}
\ No newline at end of file
+    return m_coins->getRow(index.row());
+}
index 792debe36a57e934cadfa95f953668b6256e4e81..47afb7e9c0e1be0b8608ffbbee178837eecdd861 100644 (file)
@@ -31,8 +31,6 @@ public:
 
     explicit CoinsModel(QObject *parent, Coins *coins);
 
-    Coins * coins() const;
-
     int rowCount(const QModelIndex &parent = QModelIndex()) const override;
     int columnCount(const QModelIndex &parent = QModelIndex()) const override;
     QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
@@ -40,7 +38,7 @@ public:
     Qt::ItemFlags flags(const QModelIndex &index) const override;
     bool setData(const QModelIndex &index, const QVariant &value, int role) override;
 
-    CoinsInfo* entryFromIndex(const QModelIndex &index) const;
+    const CoinsInfo& entryFromIndex(const QModelIndex &index) const;
 
     void setCurrentSubaddressAccount(quint32 accountIndex);
     void setSelected(const QStringList &selected);
index d4ef233622dae775cca6ebdf66a4428e2bbc0309..193f428081cca1792b1ae5ffd3a10a18f709185d 100644 (file)
@@ -26,16 +26,16 @@ void CoinsProxyModel::setSearchFilter(const QString &searchString) {
 
 bool CoinsProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
 {
-    CoinsInfo* coin = m_coins->coin(sourceRow);
+    const CoinsInfo& coin = m_coins->getRow(sourceRow);
 
-    if (!m_showSpent && coin->spent()) {
+    if (!m_showSpent && coin.spent) {
         return false;
     }
 
     if (!m_searchRegExp.pattern().isEmpty()) {
-        return coin->pubKey().contains(m_searchRegExp) || coin->address().contains(m_searchRegExp)
-                || coin->hash().contains(m_searchRegExp) || coin->addressLabel().contains(m_searchRegExp)
-                || coin->description().contains(m_searchRegExp);
+        return coin.pubKey.contains(m_searchRegExp) || coin.address.contains(m_searchRegExp)
+                || coin.hash.contains(m_searchRegExp) || coin.addressLabel.contains(m_searchRegExp)
+                || coin.description.contains(m_searchRegExp);
     }
 
     return true;