]> Nutra Git (v2) - gamesguru/feather.git/commitdiff
refactor: consolidate wallet_api into libwalletqt [1/?]
authortobtoht <tob@featherwallet.org>
Fri, 17 Nov 2023 13:05:31 +0000 (14:05 +0100)
committertobtoht <tob@featherwallet.org>
Fri, 17 Nov 2023 13:05:31 +0000 (14:05 +0100)
46 files changed:
src/CoinsWidget.cpp
src/ContactsWidget.cpp
src/HistoryWidget.cpp
src/MainWindow.cpp
src/dialog/AccountSwitcherDialog.cpp
src/dialog/AccountSwitcherDialog.h
src/dialog/AccountSwitcherDialog.ui
src/dialog/OutputInfoDialog.h
src/dialog/OutputSweepDialog.h
src/dialog/TxInfoDialog.cpp
src/dialog/TxInfoDialog.h
src/dialog/TxProofDialog.cpp
src/dialog/TxProofDialog.h
src/libwalletqt/AddressBook.cpp
src/libwalletqt/AddressBook.h
src/libwalletqt/AddressBookInfo.cpp [deleted file]
src/libwalletqt/AddressBookInfo.h [deleted file]
src/libwalletqt/Coins.cpp
src/libwalletqt/Coins.h
src/libwalletqt/Ring.h
src/libwalletqt/Subaddress.cpp
src/libwalletqt/SubaddressAccount.cpp
src/libwalletqt/SubaddressAccount.h
src/libwalletqt/TransactionHistory.cpp
src/libwalletqt/TransactionHistory.h
src/libwalletqt/TransactionInfo.cpp [deleted file]
src/libwalletqt/Transfer.h
src/libwalletqt/Wallet.cpp
src/libwalletqt/rows/AccountRow.cpp [new file with mode: 0644]
src/libwalletqt/rows/AccountRow.h [new file with mode: 0644]
src/libwalletqt/rows/CoinsInfo.cpp [moved from src/libwalletqt/CoinsInfo.cpp with 60% similarity]
src/libwalletqt/rows/CoinsInfo.h [moved from src/libwalletqt/CoinsInfo.h with 58% similarity]
src/libwalletqt/rows/ContactRow.cpp [new file with mode: 0644]
src/libwalletqt/rows/ContactRow.h [new file with mode: 0644]
src/libwalletqt/rows/TransactionRow.cpp [new file with mode: 0644]
src/libwalletqt/rows/TransactionRow.h [moved from src/libwalletqt/TransactionInfo.h with 54% similarity]
src/model/AddressBookModel.cpp
src/model/CoinsModel.cpp
src/model/CoinsProxyModel.cpp
src/model/HistoryView.cpp
src/model/HistoryView.h
src/model/SubaddressAccountModel.cpp
src/model/SubaddressAccountModel.h
src/model/TransactionHistoryModel.cpp
src/model/TransactionHistoryModel.h
src/model/TransactionHistoryProxyModel.cpp

index 34c82e7e103a562230da4b43c5f2634ddcfa4083..94825a140ec783cf9db7fbd0f2fd4e3d6950a477 100644 (file)
@@ -299,7 +299,7 @@ void CoinsWidget::freezeCoins(QStringList &pubkeys) {
     for (auto &pubkey : pubkeys) {
         m_wallet->coins()->freeze(pubkey);
     }
-    m_wallet->coins()->refresh(m_wallet->currentSubaddressAccount());
+    m_wallet->coins()->refresh();
     m_wallet->updateBalance();
 }
 
@@ -307,7 +307,7 @@ void CoinsWidget::thawCoins(QStringList &pubkeys) {
     for (auto &pubkey : pubkeys) {
         m_wallet->coins()->thaw(pubkey);
     }
-    m_wallet->coins()->refresh(m_wallet->currentSubaddressAccount());
+    m_wallet->coins()->refresh();
     m_wallet->updateBalance();
 }
 
index d2a332a6a01163a3f75310884c1b9315c5a49b6e..ecb67fbbb0cd823a14e4324153b20967cdab02b9 100644 (file)
@@ -135,9 +135,9 @@ void ContactsWidget::newContact(QString address, QString name)
     QString address_entry;
     QString name_entry;
     for (int i=0; i<num_addresses; i++) {
-        m_wallet->addressBook()->getRow(i, [&address_entry, &name_entry](const AddressBookInfo &entry){
-            address_entry = entry.address();
-            name_entry = entry.description();
+        m_wallet->addressBook()->getRow(i, [&address_entry, &name_entry](const ContactRow &entry){
+            address_entry = entry.getAddress();
+            name_entry = entry.getLabel();
         });
 
         if (address == address_entry) {
@@ -152,7 +152,7 @@ void ContactsWidget::newContact(QString address, QString name)
         }
     }
 
-    m_wallet->addressBook()->addRow(address, "", name);
+    m_wallet->addressBook()->addRow(address, name);
 }
 
 void ContactsWidget::deleteContact()
index 2f80059ff244eeb782450829c6472812c3b054ac..cb2983606c87ff4a3b3d8050847dc1a870c417d0 100644 (file)
@@ -86,7 +86,7 @@ void HistoryWidget::showContextMenu(const QPoint &point) {
     if (!tx) return;
 
     bool unconfirmed = tx->isFailed() || tx->isPending();
-    if (unconfirmed && tx->direction() != TransactionInfo::Direction_In) {
+    if (unconfirmed && tx->direction() != TransactionRow::Direction_In) {
         menu.addAction("Resend transaction", this, &HistoryWidget::onResendTransaction);
     }
 
index 7a83971744a4c6c8ef073ba7ce2e55afa15621ee..f2578e2958afa55cb31bf3aa703d4ded94276a10 100644 (file)
@@ -22,7 +22,7 @@
 #include "dialog/WalletInfoDialog.h"
 #include "dialog/WalletCacheDebugDialog.h"
 #include "libwalletqt/AddressBook.h"
-#include "libwalletqt/CoinsInfo.h"
+#include "libwalletqt/rows/CoinsInfo.h"
 #include "libwalletqt/Transfer.h"
 #include "utils/AppData.h"
 #include "utils/AsyncTask.h"
@@ -502,20 +502,20 @@ void MainWindow::onWalletOpened() {
     m_wallet->subaddressModel()->setCurrentSubaddressAccount(m_wallet->currentSubaddressAccount());
 
     // history page
-    m_wallet->history()->refresh(m_wallet->currentSubaddressAccount());
+    m_wallet->history()->refresh();
 
     // coins page
-    m_wallet->coins()->refresh(m_wallet->currentSubaddressAccount());
+    m_wallet->coins()->refresh();
     m_coinsWidget->setModel(m_wallet->coinsModel(), m_wallet->coins());
     m_wallet->coinsModel()->setCurrentSubaddressAccount(m_wallet->currentSubaddressAccount());
 
     // Coin labeling uses set_tx_note, so we need to refresh history too
     connect(m_wallet->coins(), &Coins::descriptionChanged, [this] {
-        m_wallet->history()->refresh(m_wallet->currentSubaddressAccount());
+        m_wallet->history()->refresh();
     });
     // Vice versa
     connect(m_wallet->history(), &TransactionHistory::txNoteChanged, [this] {
-        m_wallet->coins()->refresh(m_wallet->currentSubaddressAccount());
+        m_wallet->coins()->refresh();
     });
 
     this->updatePasswordIcon();
@@ -898,7 +898,7 @@ void MainWindow::onTransactionCommitted(bool success, PendingTransaction *tx, co
     msgBox.exec();
     if (msgBox.clickedButton() == showDetailsButton) {
         this->showHistoryTab();
-        TransactionInfo *txInfo = m_wallet->history()->transaction(txid.first());
+        TransactionRow *txInfo = m_wallet->history()->transaction(txid.first());
         auto *dialog = new TxInfoDialog(m_wallet, txInfo, this);
         connect(dialog, &TxInfoDialog::resendTranscation, this, &MainWindow::onResendTransaction);
         dialog->show();
@@ -1145,7 +1145,7 @@ void MainWindow::importContacts() {
         i.next();
         bool addressValid = WalletManager::addressValid(i.value(), m_wallet->nettype());
         if(addressValid) {
-            m_wallet->addressBook()->addRow(i.value(), "", i.key());
+            m_wallet->addressBook()->addRow(i.value(), i.key());
             inserts++;
         }
     }
index 9977bda38f4d6c07acf1a8e04ddf259c05521d6f..49c32f6b429024238f98b7155651b240a1a04a13 100644 (file)
@@ -64,7 +64,7 @@ void AccountSwitcherDialog::switchAccount() {
         return;
     }
 
-    m_wallet->switchSubaddressAccount(row->getRowId());
+    m_wallet->switchSubaddressAccount(row->getRow());
 }
 
 void AccountSwitcherDialog::copyLabel() {
@@ -73,7 +73,7 @@ void AccountSwitcherDialog::copyLabel() {
         return;
     }
 
-    Utils::copyToClipboard(QString::fromStdString(row->getLabel()));
+    Utils::copyToClipboard(row->getLabel());
 }
 
 void AccountSwitcherDialog::copyBalance() {
@@ -82,7 +82,7 @@ void AccountSwitcherDialog::copyBalance() {
         return;
     }
 
-    Utils::copyToClipboard(QString::fromStdString(row->getBalance()));
+    Utils::copyToClipboard(row->getBalance());
 }
 
 void AccountSwitcherDialog::editLabel() {
@@ -93,6 +93,9 @@ void AccountSwitcherDialog::editLabel() {
 
 void AccountSwitcherDialog::updateSelection() {
     QModelIndex index = m_model->index(m_wallet->currentSubaddressAccount(), 0);
+    if (!index.isValid()) {
+        return;
+    }
     ui->accounts->selectionModel()->select(index, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
 }
 
@@ -111,7 +114,7 @@ void AccountSwitcherDialog::showContextMenu(const QPoint &point) {
     menu->popup(ui->accounts->viewport()->mapToGlobal(point));
 }
 
-Monero::SubaddressAccountRow* AccountSwitcherDialog::currentEntry() {
+AccountRow* AccountSwitcherDialog::currentEntry() {
     QModelIndex index = m_proxyModel->mapToSource(ui->accounts->currentIndex());
     return m_wallet->subaddressAccountModel()->entryFromIndex(index);
 }
index 5e3c6bb3bbd2bcbc1e8a17e08ec575b4927e8586..568041e2a926184eebaeed4b672c01584b604f93 100644 (file)
@@ -34,7 +34,7 @@ private:
     void copyBalance();
     void editLabel();
 
-    Monero::SubaddressAccountRow* currentEntry();
+    AccountRow* currentEntry();
 
     QScopedPointer<Ui::AccountSwitcherDialog> ui;
     Wallet *m_wallet;
index 1b203cfd120a318d2de1676be8a99540d2dbf7e2..e23ccc74c89cfcd2c7159923cd820827b35c3241 100644 (file)
@@ -16,9 +16,6 @@
   <layout class="QVBoxLayout" name="verticalLayout">
    <item>
     <widget class="QTreeView" name="accounts">
-     <property name="focusPolicy">
-      <enum>Qt::NoFocus</enum>
-     </property>
      <property name="rootIsDecorated">
       <bool>false</bool>
      </property>
index 729d5d06c56386863d155f8e00c66e396f0bd662..0a4080f03d2a7824384b74d228cd8f57cb1577c3 100644 (file)
@@ -8,7 +8,7 @@
 
 #include "components.h"
 #include "libwalletqt/Coins.h"
-#include "libwalletqt/CoinsInfo.h"
+#include "libwalletqt/rows/CoinsInfo.h"
 
 namespace Ui {
     class OutputInfoDialog;
index 7907b2ccf6054db62e6c51359d07c88497d17fa8..9372b9ef4353a367f5ddf0209121ee5eb349cfe6 100644 (file)
@@ -7,7 +7,7 @@
 #include <QDialog>
 
 #include "components.h"
-#include "libwalletqt/CoinsInfo.h"
+#include "libwalletqt/rows/CoinsInfo.h"
 
 namespace Ui {
     class OutputSweepDialog;
index 4b5e3d839ae0e3acc35484b39f6e6204a382cf0a..3d2ddc2afa685a5aed0591dbbef6e3698c2ccf42 100644 (file)
 #include "config.h"
 #include "constants.h"
 #include "libwalletqt/Coins.h"
-#include "libwalletqt/CoinsInfo.h"
+#include "libwalletqt/rows/CoinsInfo.h"
 #include "libwalletqt/TransactionHistory.h"
 #include "libwalletqt/Transfer.h"
 #include "libwalletqt/WalletManager.h"
 #include "utils/Icons.h"
 #include "utils/Utils.h"
 
-TxInfoDialog::TxInfoDialog(Wallet *wallet, TransactionInfo *txInfo, QWidget *parent)
+TxInfoDialog::TxInfoDialog(Wallet *wallet, TransactionRow *txInfo, QWidget *parent)
     : QDialog(parent)
     , ui(new Ui::TxInfoDialog)
     , m_wallet(wallet)
@@ -41,7 +41,7 @@ TxInfoDialog::TxInfoDialog(Wallet *wallet, TransactionInfo *txInfo, QWidget *par
 
     this->setData(txInfo);
 
-    if ((txInfo->isFailed() || txInfo->isPending()) && txInfo->direction() != TransactionInfo::Direction_In) {
+    if ((txInfo->isFailed() || txInfo->isPending()) && txInfo->direction() != TransactionRow::Direction_In) {
         connect(ui->btn_rebroadcastTx, &QPushButton::pressed, [this]{
             emit resendTranscation(m_txid);
         });
@@ -49,7 +49,7 @@ TxInfoDialog::TxInfoDialog(Wallet *wallet, TransactionInfo *txInfo, QWidget *par
         ui->btn_rebroadcastTx->hide();
     }
 
-    if (txInfo->direction() == TransactionInfo::Direction_In) {
+    if (txInfo->direction() == TransactionRow::Direction_In) {
         ui->btn_CopyTxKey->setDisabled(true);
         ui->btn_CopyTxKey->setToolTip("No tx secret key available for incoming transactions.");
     }
@@ -106,7 +106,7 @@ void TxInfoDialog::adjustHeight(QTextEdit *textEdit, qreal docHeight) {
     textEdit->verticalScrollBar()->hide();
 }
 
-void TxInfoDialog::setData(TransactionInfo *tx) {
+void TxInfoDialog::setData(TransactionRow *tx) {
     QString blockHeight = QString::number(tx->blockHeight());
 
     if (tx->isFailed()) {
@@ -131,13 +131,13 @@ void TxInfoDialog::setData(TransactionInfo *tx) {
         ui->label_lock->setText("Lock: Outputs are spendable");
     }
 
-    QString direction = tx->direction() == TransactionInfo::Direction_In ? "received" : "sent";
+    QString direction = tx->direction() == TransactionRow::Direction_In ? "received" : "sent";
     ui->label_amount->setText(QString("Amount %1: %2 XMR").arg(direction, tx->displayAmount()));
 
     QString fee;
     if (tx->isCoinbase())
         fee = "Not applicable";
-    else if (tx->direction() == TransactionInfo::Direction_In)
+    else if (tx->direction() == TransactionRow::Direction_In)
         fee = "Paid by sender";
     else if (tx->fee().isEmpty())
         fee = "N/A";
@@ -149,7 +149,7 @@ void TxInfoDialog::setData(TransactionInfo *tx) {
 }
 
 void TxInfoDialog::updateData() {
-    TransactionInfo *tx = m_wallet->history()->transaction(m_txid);
+    TransactionRow *tx = m_wallet->history()->transaction(m_txid);
     if (!tx) return;
     this->setData(tx);
 }
index b80e9e4a5614e958b2c78c44868246b351b33a4d..4ad0cf0090125e4539f1f8738bce8c279dc197fc 100644 (file)
@@ -10,6 +10,7 @@
 #include <QSvgWidget>
 
 #include "dialog/TxProofDialog.h"
+#include "libwalletqt/rows/TransactionRow.h"
 
 namespace Ui {
     class TxInfoDialog;
@@ -20,7 +21,7 @@ class TxInfoDialog : public QDialog
 Q_OBJECT
 
 public:
-    explicit TxInfoDialog(Wallet *wallet, TransactionInfo *txInfo, QWidget *parent = nullptr);
+    explicit TxInfoDialog(Wallet *wallet, TransactionRow *txInfo, QWidget *parent = nullptr);
     ~TxInfoDialog() override;
 
 signals:
@@ -30,14 +31,14 @@ private:
     void copyTxID();
     void copyTxKey();
     void createTxProof();
-    void setData(TransactionInfo *tx);
+    void setData(TransactionRow *tx);
     void updateData();
     void adjustHeight(QTextEdit *textEdit, qreal docHeight);
     void viewOnBlockExplorer();
 
     QScopedPointer<Ui::TxInfoDialog> ui;
     Wallet *m_wallet;
-    TransactionInfo *m_txInfo;
+    TransactionRow *m_txInfo;
     TxProofDialog *m_txProofDialog;
     QString m_txid;
 };
index 4a3650d7ad67d68a33dbb85c60f27bf50e71bc73..b865ac1723d3457280578b4fa5af6bbc59b8faa7 100644 (file)
@@ -10,7 +10,7 @@
 #include "utils/Icons.h"
 #include "utils/Utils.h"
 
-TxProofDialog::TxProofDialog(QWidget *parent, Wallet *wallet, TransactionInfo *txInfo)
+TxProofDialog::TxProofDialog(QWidget *parent, Wallet *wallet, TransactionRow *txInfo)
     : WindowModalDialog(parent)
     , ui(new Ui::TxProofDialog)
     , m_wallet(wallet)
@@ -70,7 +70,7 @@ void TxProofDialog::selectSpendProof() {
     m_mode = Mode::SpendProof;
     this->resetFrames();
 
-    if (m_direction == TransactionInfo::Direction_In) {
+    if (m_direction == TransactionRow::Direction_In) {
         this->showWarning("Your wallet did not construct this transaction. Creating a SpendProof is not possible.");
         return;
     }
@@ -107,7 +107,7 @@ void TxProofDialog::selectInProof() {
     m_mode = Mode::InProof;
     this->resetFrames();
 
-    if (m_direction == TransactionInfo::Direction_Out) {
+    if (m_direction == TransactionRow::Direction_Out) {
         this->showWarning("Can't create InProofs for outgoing transactions.");
         return;
     }
index 8f14d977bf4a850c745776310b70cbc2f9624f8f..215946a79f26101ed4f32964f822e904e0ae155f 100644 (file)
@@ -7,8 +7,8 @@
 #include <QDialog>
 
 #include "components.h"
-#include "libwalletqt/TransactionInfo.h"
 #include "libwalletqt/Wallet.h"
+#include "rows/TransactionRow.h"
 
 namespace Ui {
     class TxProofDialog;
@@ -19,7 +19,7 @@ class TxProofDialog : public WindowModalDialog
     Q_OBJECT
 
 public:
-    explicit TxProofDialog(QWidget *parent, Wallet *wallet, TransactionInfo *txid);
+    explicit TxProofDialog(QWidget *parent, Wallet *wallet, TransactionRow *txid);
     ~TxProofDialog() override;
     void setTxId(const QString &txid);
     void getTxKey();
@@ -52,7 +52,7 @@ private:
     QString m_txid;
     QString m_txKey;
     Mode m_mode;
-    TransactionInfo::Direction m_direction;
+    TransactionRow::Direction m_direction;
 };
 
 #endif //FEATHER_TXPROOFDIALOG_H
index d4230453449634382ca7f901725966aad004c9cb..607bd92da59d38515d2a5cf4bc3b27e723efaf2b 100644 (file)
@@ -4,48 +4,54 @@
 #include "AddressBook.h"
 #include <QDebug>
 
-AddressBook::AddressBook(Monero::AddressBook *abImpl, QObject *parent)
-  : QObject(parent), m_addressBookImpl(abImpl)
+AddressBook::AddressBook(Wallet *wallet, tools::wallet2 *wallet2, QObject *parent)
+     : QObject(parent)
+     , m_wallet(wallet)
+     , m_wallet2(wallet2)
 {
-    getAll();
+    this->refresh();
 }
 
 QString AddressBook::errorString() const
 {
-    return QString::fromStdString(m_addressBookImpl->errorString());
+    return m_errorString;
 }
 
-int AddressBook::errorCode() const
+AddressBook::ErrorCode AddressBook::errorCode() const
 {
-    return m_addressBookImpl->errorCode();
+    return m_errorCode;
 }
 
-void AddressBook::getAll()
+void AddressBook::refresh()
 {
     emit refreshStarted();
 
-    {
-        QWriteLocker locker(&m_lock);
-
-        qDeleteAll(m_rows);
+    clearRows();
 
-        m_addresses.clear();
-        m_rows.clear();
+    // Fetch from Wallet2 and create vector of AddressBookRow objects
+    std::vector<tools::wallet2::address_book_row> rows = m_wallet2->get_address_book();
+    for (qsizetype i = 0; i < rows.size(); ++i) {
+        tools::wallet2::address_book_row *row = &rows.at(i);
 
-        for (auto &abr: m_addressBookImpl->getAll()) {
-            m_addresses.insert(QString::fromStdString(abr->getAddress()), m_rows.size());
+        std::string address;
+        if (row->m_has_payment_id)
+            address = cryptonote::get_account_integrated_address_as_str(m_wallet2->nettype(), row->m_address, row->m_payment_id);
+        else
+            address = get_account_address_as_str(m_wallet2->nettype(), row->m_is_subaddress, row->m_address);
 
-            m_rows.append(new AddressBookInfo(abr, this));
-        }
+        auto* abr = new ContactRow{this,
+                                   i,
+                                   QString::fromStdString(address),
+                                   QString::fromStdString(row->m_description)};
+        m_rows.push_back(abr);
     }
 
+
     emit refreshFinished();
 }
 
-bool AddressBook::getRow(int index, std::function<void (AddressBookInfo &)> callback) const
+bool AddressBook::getRow(int index, std::function<void (ContactRow &)> callback) const
 {
-    QReadLocker locker(&m_lock);
-
     if (index < 0 || index >= m_rows.size())
     {
         return false;
@@ -55,88 +61,58 @@ bool AddressBook::getRow(int index, std::function<void (AddressBookInfo &)> call
     return true;
 }
 
-bool AddressBook::addRow(const QString &address, const QString &payment_id, const QString &description)
+bool AddressBook::addRow(const QString &address, const QString &description)
 {
-    //  virtual bool addRow(const std::string &dst_addr , const std::string &payment_id, const std::string &description) = 0;
-    bool result;
+    m_errorString = "";
 
-    {
-        QWriteLocker locker(&m_lock);
-
-        result = m_addressBookImpl->addRow(address.toStdString(), payment_id.toStdString(), description.toStdString());
-    }
-
-    if (result)
-    {
-        getAll();
+    cryptonote::address_parse_info info;
+    if (!cryptonote::get_account_address_from_str(info, m_wallet2->nettype(), address.toStdString())) {
+        m_errorString = tr("Invalid destination address");
+        m_errorCode = Invalid_Address;
+        return false;
     }
 
-    return result;
+    bool r =  m_wallet2->add_address_book_row(info.address, info.has_payment_id ? &info.payment_id : nullptr, description.toStdString(), info.is_subaddress);
+    if (r)
+        refresh();
+    else
+        m_errorCode = General_Error;
+    return r;
 }
 
-void AddressBook::setDescription(int index, const QString &description) {
-    bool result;
-
-    {
-        QWriteLocker locker(&m_lock);
+bool AddressBook::setDescription(int index, const QString &description) {
+    m_errorString = "";
 
-        result = m_addressBookImpl->setDescription(index, description.toStdString());
+    const auto ab = m_wallet2->get_address_book();
+    if (index >= ab.size()){
+        return false;
     }
 
-    if (result)
-    {
-        getAll();
-        emit descriptionChanged();
-    }
+    tools::wallet2::address_book_row entry = ab[index];
+    entry.m_description = description.toStdString();
+    bool r =  m_wallet2->set_address_book_row(index, entry.m_address, entry.m_has_payment_id ? &entry.m_payment_id : nullptr, entry.m_description, entry.m_is_subaddress);
+    if (r)
+        refresh();
+    else
+        m_errorCode = General_Error;
+    return r;
 }
 
 bool AddressBook::deleteRow(int rowId)
 {
-    bool result;
-
-    {
-        QWriteLocker locker(&m_lock);
-
-        result = m_addressBookImpl->deleteRow(rowId);
-    }
-
-    // Fetch new data from wallet2.
-    if (result)
-    {
-        getAll();
-    }
-
-    return result;
-}
-
-quint64 AddressBook::count() const
-{
-    QReadLocker locker(&m_lock);
-
-    return m_rows.size();
+    bool r = m_wallet2->delete_address_book_row(rowId);
+    if (r)
+        refresh();
+    return r;
 }
 
-QString AddressBook::getDescription(const QString &address) const
+qsizetype AddressBook::count() const
 {
-    QReadLocker locker(&m_lock);
-
-    const QMap<QString, size_t>::const_iterator it = m_addresses.find(address);
-    if (it == m_addresses.end())
-    {
-        return {};
-    }
-    return m_rows.value(*it)->description();
+    return m_rows.length();
 }
 
-QString AddressBook::getAddress(const QString &description) const
+void AddressBook::clearRows()
 {
-    QReadLocker locker(&m_lock);
-
-    for (const auto &row : m_rows) {
-        if (row->description() == description) {
-            return row->address();
-        }
-    }
-
-    return QString();
+    qDeleteAll(m_rows);
+    m_rows.clear();
 }
\ No newline at end of file
index 2b7fd30d59c185161273a5e1ddb64c53585c0e0c..b9e7f2095814e01e5a90f22c016557d5a496026d 100644 (file)
@@ -5,43 +5,44 @@
 #define ADDRESSBOOK_H
 
 #include <wallet/api/wallet2_api.h>
-#include "AddressBookInfo.h"
 #include <QMap>
 #include <QObject>
 #include <QReadWriteLock>
 #include <QList>
 #include <QDateTime>
 
+#include "rows/ContactRow.h"
+#include "Wallet.h"
+#include "wallet/wallet2.h"
+
 namespace Monero {
 struct AddressBook;
 }
-class AddressBookRow;
 
 class AddressBook : public QObject
 {
     Q_OBJECT
-public:
-    Q_INVOKABLE bool getRow(int index, std::function<void (AddressBookInfo &)> callback) const;
-    Q_INVOKABLE bool addRow(const QString &address, const QString &payment_id, const QString &description);
-    Q_INVOKABLE bool deleteRow(int rowId);
-    Q_INVOKABLE void setDescription(int index, const QString &label);
-    quint64 count() const;
-    Q_INVOKABLE QString errorString() const;
-    Q_INVOKABLE int errorCode() const;
-    Q_INVOKABLE QString getDescription(const QString &address) const;
-    Q_INVOKABLE QString getAddress(const QString &description) const;
 
+public:
     enum ErrorCode {
         Status_Ok,
         General_Error,
         Invalid_Address,
         Invalid_Payment_Id
     };
-
     Q_ENUM(ErrorCode);
 
-private:
-    void getAll();
+    bool getRow(int index, std::function<void (ContactRow &)> callback) const;
+    bool addRow(const QString &address, const QString &description);
+    bool deleteRow(int rowId);
+    bool setDescription(int index, const QString &label);
+    qsizetype count() const;
+    QString errorString() const;
+    ErrorCode errorCode() const;
+
+    void refresh();
+    void clearRows();
+
 
 signals:
     void refreshStarted() const;
@@ -49,12 +50,15 @@ signals:
     void descriptionChanged() const;
 
 private:
-    explicit AddressBook(Monero::AddressBook * abImpl, QObject *parent);
+    explicit AddressBook(Wallet *wallet, tools::wallet2 *wallet2, QObject *parent);
     friend class Wallet;
-    Monero::AddressBook * m_addressBookImpl;
-    mutable QReadWriteLock m_lock;
-    QList<AddressBookInfo*> m_rows;
-    QMap<QString, size_t> m_addresses;
+
+    Wallet *m_wallet;
+    tools::wallet2 *m_wallet2;
+    QList<ContactRow*> m_rows;
+
+    QString m_errorString;
+    ErrorCode m_errorCode;
 };
 
 #endif // ADDRESSBOOK_H
diff --git a/src/libwalletqt/AddressBookInfo.cpp b/src/libwalletqt/AddressBookInfo.cpp
deleted file mode 100644 (file)
index b2e4ee7..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-// SPDX-License-Identifier: BSD-3-Clause
-// SPDX-FileCopyrightText: 2020-2023 The Monero Project
-
-#include "AddressBookInfo.h"
-
-QString AddressBookInfo::address() const {
-    return m_address;
-}
-
-QString AddressBookInfo::description() const {
-    return m_description;
-}
-
-AddressBookInfo::AddressBookInfo(const Monero::AddressBookRow *pimpl, QObject *parent)
-        : QObject(parent)
-        , m_address(QString::fromStdString(pimpl->getAddress()))
-        , m_description(QString::fromStdString(pimpl->getDescription()))
-{
-
-}
diff --git a/src/libwalletqt/AddressBookInfo.h b/src/libwalletqt/AddressBookInfo.h
deleted file mode 100644 (file)
index cd653bf..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-// SPDX-License-Identifier: BSD-3-Clause
-// SPDX-FileCopyrightText: 2020-2023 The Monero Project
-
-#ifndef FEATHER_ADDRESSBOOKINFO_H
-#define FEATHER_ADDRESSBOOKINFO_H
-
-#include <wallet/api/wallet2_api.h>
-#include <QObject>
-
-class AddressBookInfo : public QObject {
-    Q_OBJECT
-    Q_PROPERTY(QString address READ address);
-    Q_PROPERTY(QString description READ description);
-
-public:
-    QString address() const;
-    QString description() const;
-
-private:
-    explicit AddressBookInfo(const Monero::AddressBookRow *pimpl, QObject *parent = nullptr);
-
-    friend class AddressBook;
-    QString m_address;
-    QString m_description;
-};
-
-
-#endif //FEATHER_ADDRESSBOOKINFO_H
index fb609666fab8179934a89f9abcfe1dd4295d75b6..3f74fe45452e62dcd5a6d8d2f99640f987613ef3 100644 (file)
@@ -2,50 +2,80 @@
 // SPDX-FileCopyrightText: 2020-2023 The Monero Project
 
 #include "Coins.h"
+#include "rows/CoinsInfo.h"
 
-#include <QDebug>
-
-#include "CoinsInfo.h"
-
-#include <QFile>
+Coins::Coins(Wallet *wallet, tools::wallet2 *wallet2, QObject *parent)
+        : QObject(parent)
+        , m_wallet(wallet)
+        , m_wallet2(wallet2)
+{
 
+}
 
 bool Coins::coin(int index, std::function<void (CoinsInfo &)> callback)
 {
     QReadLocker locker(&m_lock);
 
-    if (index < 0 || index >= m_tinfo.size()) {
+    if (index < 0 || index >= m_rows.size()) {
         qCritical("%s: no transaction info for index %d", __FUNCTION__, index);
-        qCritical("%s: there's %d transactions in backend", __FUNCTION__, m_pimpl->count());
+        qCritical("%s: there's %lld transactions in backend", __FUNCTION__, m_rows.count());
         return false;
     }
 
-    callback(*m_tinfo.value(index));
+    callback(*m_rows.value(index));
     return true;
 }
 
 CoinsInfo* Coins::coin(int index)
 {
-    return m_tinfo.value(index);
+    return m_rows.value(index);
 }
 
-void Coins::refresh(quint32 accountIndex)
+void Coins::refresh()
 {
     emit refreshStarted();
 
+    boost::shared_lock<boost::shared_mutex> transfers_lock(m_wallet2->m_transfers_mutex);
+
     {
         QWriteLocker locker(&m_lock);
 
-        qDeleteAll(m_tinfo);
-        m_tinfo.clear();
+        clearRows();
+        uint32_t account = m_wallet->currentSubaddressAccount();
+
+        for (size_t i = 0; i < m_wallet2->get_num_transfer_details(); ++i)
+        {
+            const tools::wallet2::transfer_details &td = m_wallet2->get_transfer_details(i);
 
-        m_pimpl->refresh();
-        for (const auto i : m_pimpl->getAll()) {
-            if (i->subaddrAccount() != accountIndex) {
+            if (td.m_subaddr_index.major != account) {
                 continue;
             }
 
-            m_tinfo.append(new CoinsInfo(i, this));
+            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_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);
+
+            m_rows.push_back(ci);
         }
     }
 
@@ -56,9 +86,9 @@ void Coins::refreshUnlocked()
 {
     QWriteLocker locker(&m_lock);
 
-    for (CoinsInfo* c : m_tinfo) {
+    for (CoinsInfo* c : m_rows) {
         if (!c->unlocked()) {
-            bool unlocked = m_pimpl->isTransferUnlocked(c->unlockTime(), c->blockHeight());
+            bool unlocked = m_wallet2->is_transfer_unlocked(c->unlockTime(), c->blockHeight());
             c->setUnlocked(unlocked);
         }
     }
@@ -68,18 +98,50 @@ quint64 Coins::count() const
 {
     QReadLocker locker(&m_lock);
 
-    return m_tinfo.count();
+    return m_rows.length();
 }
 
-void Coins::freeze(QString &publicKey) const
+void Coins::freeze(QString &publicKey)
 {
-    m_pimpl->setFrozen(publicKey.toStdString());
+    crypto::public_key pk;
+    if (!epee::string_tools::hex_to_pod(publicKey.toStdString(), pk))
+    {
+        qWarning() << "Invalid public key: " << publicKey;
+        return;
+    }
+
+    try
+    {
+        m_wallet2->freeze(pk);
+        refresh();
+    }
+    catch (const std::exception& e)
+    {
+        qWarning() << "freeze: " << e.what();
+    }
+
     emit coinFrozen();
 }
 
-void Coins::thaw(QString &publicKey) const
+void Coins::thaw(QString &publicKey)
 {
-    m_pimpl->thaw(publicKey.toStdString());
+    crypto::public_key pk;
+    if (!epee::string_tools::hex_to_pod(publicKey.toStdString(), pk))
+    {
+        qWarning() << "Invalid public key: " << publicKey;
+        return;
+    }
+
+    try
+    {
+        m_wallet2->thaw(pk);
+        refresh();
+    }
+    catch (const std::exception& e)
+    {
+        qWarning() << "thaw: " << e.what();
+    }
+
     emit coinThawed();
 }
 
@@ -111,14 +173,12 @@ QVector<CoinsInfo*> Coins::coinsFromKeyImage(const QStringList &keyimages) {
 
 void Coins::setDescription(const QString &publicKey, quint32 accountIndex, const QString &description)
 {
-    m_pimpl->setDescription(publicKey.toStdString(), description.toStdString());
-    this->refresh(accountIndex);
+    m_wallet->setCacheAttribute(QString("coin.description:%1").arg(publicKey), description);
+    this->refresh();
     emit descriptionChanged();
 }
 
-Coins::Coins(Monero::Coins *pimpl, QObject *parent)
-        : QObject(parent)
-        , m_pimpl(pimpl)
-{
-
+void Coins::clearRows() {
+    qDeleteAll(m_rows);
+    m_rows.clear();
 }
\ No newline at end of file
index 4ab96880477791655420620aa1a2b615dbdb9303..8c6e9cdd2b72fc6530b3fe0c4bcf6434f604ae93 100644 (file)
@@ -12,6 +12,9 @@
 #include <QDateTime>
 #include <wallet/api/wallet2_api.h>
 
+#include "Wallet.h"
+#include "wallet/wallet2.h"
+
 namespace Monero {
     struct TransactionHistory;
 }
@@ -25,15 +28,16 @@ Q_OBJECT
 public:
     bool coin(int index, std::function<void (CoinsInfo &)> callback);
     CoinsInfo * coin(int index);
-    void refresh(quint32 accountIndex);
+    void refresh();
     void refreshUnlocked();
-    void freeze(QString &publicKey) const;
-    void thaw(QString &publicKey) const;
+    void freeze(QString &publicKey);
+    void thaw(QString &publicKey);
     QVector<CoinsInfo*> coins_from_txid(const QString &txid);
     QVector<CoinsInfo*> coinsFromKeyImage(const QStringList &keyimages);
     void setDescription(const QString &publicKey, quint32 accountIndex, const QString &description);
 
     quint64 count() const;
+    void clearRows();
 
 signals:
     void refreshStarted() const;
@@ -43,13 +47,16 @@ signals:
     void descriptionChanged() const;
 
 private:
-    explicit Coins(Monero::Coins * pimpl, QObject *parent = nullptr);
+    explicit Coins(Wallet *wallet, tools::wallet2 *wallet2, QObject *parent = nullptr);
 
 private:
     friend class Wallet;
+
+    Wallet *m_wallet;
+    tools::wallet2 *m_wallet2;
+    QList<CoinsInfo*> m_rows;
+
     mutable QReadWriteLock m_lock;
-    Monero::Coins * m_pimpl;
-    mutable QList<CoinsInfo*> m_tinfo;
 };
 
 #endif //FEATHER_COINS_H
index ceb27147bb0aaba5892a65b48c263e5494d9aceb..aa0d558b07f38e05b209aa1c6b1dc2e75bfeec3e 100644 (file)
 class Ring : public QObject
 {
 Q_OBJECT
-    Q_PROPERTY(QString keyImage READ keyImage)
-    Q_PROPERTY(std::vector<uint64_t> ringMembers READ ringMembers)
-private:
+
+public:
     explicit Ring(QString _keyImage, std::vector<uint64_t> _ringMembers, QObject *parent = nullptr): QObject(parent), m_keyImage(std::move(_keyImage)), m_ringMembers(std::move(_ringMembers)) {};
+
 private:
     friend class TransactionInfo;
     QString m_keyImage;
     std::vector<uint64_t> m_ringMembers;
+
 public:
     QString keyImage() const { return m_keyImage; }
     std::vector<uint64_t> ringMembers() const { return m_ringMembers; }
index 13374c90f151484095f66ec145a2fe4da0705a74..d33072dcbdcaa52564bda076330400910d801484 100644 (file)
@@ -159,8 +159,8 @@ void Subaddress::clearRows() {
 
 SubaddressRow* Subaddress::row(int index) const {
     return m_rows.value(index);
-};
+}
 
 QString Subaddress::getError() const {
     return m_errorString;
-};
\ No newline at end of file
+}
\ No newline at end of file
index 60f6fd04a54169dc081601ffb555b8f1ae1e2d11..16db72f4cf74487918a052d99651538218247d61 100644 (file)
@@ -4,31 +4,15 @@
 #include "SubaddressAccount.h"
 #include <QDebug>
 
-SubaddressAccount::SubaddressAccount(Monero::SubaddressAccount *subaddressAccountImpl, QObject *parent)
-  : QObject(parent), m_subaddressAccountImpl(subaddressAccountImpl)
+SubaddressAccount::SubaddressAccount(Wallet *wallet, tools::wallet2 *wallet2, QObject *parent)
+    : QObject(parent)
+    , m_wallet(wallet)
+    , m_wallet2(wallet2)
 {
-    getAll();
 }
 
-void SubaddressAccount::getAll() const
+bool SubaddressAccount::getRow(int index, std::function<void (AccountRow &row)> callback) const
 {
-    emit refreshStarted();
-
-    {
-        QWriteLocker locker(&m_lock);
-        m_rows.clear();
-        for (auto &row: m_subaddressAccountImpl->getAll()) {
-            m_rows.append(row);
-        }
-    }
-
-    emit refreshFinished();
-}
-
-bool SubaddressAccount::getRow(int index, std::function<void (Monero::SubaddressAccountRow &)> callback) const
-{
-    QReadLocker locker(&m_lock);
-
     if (index < 0 || index >= m_rows.size())
     {
         return false;
@@ -38,32 +22,50 @@ bool SubaddressAccount::getRow(int index, std::function<void (Monero::Subaddress
     return true;
 }
 
-void SubaddressAccount::addRow(const QString &label) const
+void SubaddressAccount::addRow(const QString &label)
 {
-    m_subaddressAccountImpl->addRow(label.toStdString());
-    getAll();
+    m_wallet2->add_subaddress_account(label.toStdString());
+    refresh();
 }
 
-void SubaddressAccount::setLabel(quint32 accountIndex, const QString &label) const
+void SubaddressAccount::setLabel(quint32 accountIndex, const QString &label)
 {
-    m_subaddressAccountImpl->setLabel(accountIndex, label.toStdString());
-    getAll();
+    m_wallet2->set_subaddress_label({accountIndex, 0}, label.toStdString());
+    refresh();
 }
 
-void SubaddressAccount::refresh() const
+void SubaddressAccount::refresh()
 {
-    m_subaddressAccountImpl->refresh();
-    getAll();
+    emit refreshStarted();
+
+    this->clearRows();
+    for (uint32_t i = 0; i < m_wallet2->get_num_subaddress_accounts(); ++i)
+    {
+        auto *row = new AccountRow{this,
+                                   i,
+                                   QString::fromStdString(m_wallet2->get_subaddress_as_str({i,0})),
+                                   QString::fromStdString(m_wallet2->get_subaddress_label({i,0})),
+                                   m_wallet2->balance(i, false),
+                                   m_wallet2->unlocked_balance(i, false)};
+
+        m_rows.append(row);
+    }
+
+    emit refreshFinished();
 }
 
-quint64 SubaddressAccount::count() const
+qsizetype SubaddressAccount::count() const
 {
-    QReadLocker locker(&m_lock);
+    return m_rows.length();
+}
 
-    return m_rows.size();
+void SubaddressAccount::clearRows()
+{
+    qDeleteAll(m_rows);
+    m_rows.clear();
 }
 
-Monero::SubaddressAccountRow* SubaddressAccount::row(int index) const
+AccountRow* SubaddressAccount::row(int index) const
 {
     return m_rows.value(index);
 }
\ No newline at end of file
index fd3add9f4e1312ddc610898742e2e124848e49ca..28957b40fdedef2ade81713455f0f9964bd783f8 100644 (file)
 #include <QList>
 #include <QDateTime>
 
+#include <wallet/wallet2.h>
+
+#include "Wallet.h"
+#include "rows/AccountRow.h"
+
 class SubaddressAccount : public QObject
 {
     Q_OBJECT
+
 public:
-    Q_INVOKABLE void getAll() const;
-    Q_INVOKABLE bool getRow(int index, std::function<void (Monero::SubaddressAccountRow &)> callback) const;
-    Q_INVOKABLE void addRow(const QString &label) const;
-    Q_INVOKABLE void setLabel(quint32 accountIndex, const QString &label) const;
-    Q_INVOKABLE void refresh() const;
-    quint64 count() const;
-    Monero::SubaddressAccountRow* row(int index) const;
+    void getAll() const;
+    bool getRow(int index, std::function<void (AccountRow &row)> callback) const;
+    void addRow(const QString &label);
+
+    void setLabel(quint32 accountIndex, const QString &label);
+
+    void refresh();
+
+    qsizetype count() const;
+    void clearRows();
+
+    AccountRow* row(int index) const;
 
 signals:
     void refreshStarted() const;
     void refreshFinished() const;
 
-public slots:
-
 private:
-    explicit SubaddressAccount(Monero::SubaddressAccount * subaddressAccountImpl, QObject *parent);
+    explicit SubaddressAccount(Wallet *wallet, tools::wallet2 *wallet2, QObject *parent);
     friend class Wallet;
-    mutable QReadWriteLock m_lock;
-    Monero::SubaddressAccount * m_subaddressAccountImpl;
-    mutable QList<Monero::SubaddressAccountRow*> m_rows;
+
+    Wallet *m_wallet;
+    tools::wallet2 *m_wallet2;
+    QList<AccountRow*> m_rows;
 };
 
 #endif // SUBADDRESSACCOUNT_H
index 2a5877e6f2ce34bdf8f667dea2b90329c9ea3064..d3bf977fcabe692d7a9c950bbcb1aecba5436f1d 100644 (file)
@@ -2,48 +2,49 @@
 // SPDX-FileCopyrightText: 2020-2023 The Monero Project
 
 #include "TransactionHistory.h"
-#include "TransactionInfo.h"
 #include "utils/Utils.h"
 #include "utils/AppData.h"
 #include "utils/config.h"
 #include "constants.h"
 #include "WalletManager.h"
+#include "Transfer.h"
+#include "Ring.h"
 
-bool TransactionHistory::transaction(int index, std::function<void (TransactionInfo &)> callback)
+bool TransactionHistory::transaction(int index, std::function<void (TransactionRow &)> callback)
 {
     QReadLocker locker(&m_lock);
 
-    if (index < 0 || index >= m_tinfo.size()) {
+    if (index < 0 || index >= m_rows.size()) {
         qCritical("%s: no transaction info for index %d", __FUNCTION__, index);
-        qCritical("%s: there's %d transactions in backend", __FUNCTION__, m_pimpl->count());
+        qCritical("%s: there's %d transactions in backend", __FUNCTION__, this->count());
         return false;
     }
 
-    callback(*m_tinfo.value(index));
+    callback(*m_rows.value(index));
     return true;
 }
 
-TransactionInfo* TransactionHistory::transaction(const QString &id)
+TransactionRow* TransactionHistory::transaction(const QString &id)
 {
     QReadLocker locker(&m_lock);
 
-    auto itr = std::find_if(m_tinfo.begin(), m_tinfo.end(),
-            [&](const TransactionInfo * ti) {
+    auto itr = std::find_if(m_rows.begin(), m_rows.end(),
+            [&](const TransactionRow * ti) {
         return ti->hash() == id;
     });
-    return itr != m_tinfo.end() ? *itr : nullptr;
+    return itr != m_rows.end() ? *itr : nullptr;
 }
 
-TransactionInfo* TransactionHistory::transaction(int index)
+TransactionRow* TransactionHistory::transaction(int index)
 {
-    if (index < 0 || index >= m_tinfo.size()) {
+    if (index < 0 || index >= m_rows.size()) {
         return nullptr;
     }
 
-    return m_tinfo[index];
+    return m_rows[index];
 }
 
-void TransactionHistory::refresh(quint32 accountIndex)
+void TransactionHistory::refresh()
 {
     QDateTime firstDateTime = QDate(2014, 4, 18).startOfDay();
     QDateTime lastDateTime  = QDateTime::currentDateTime().addDays(1); // tomorrow (guard against jitter and timezones)
@@ -53,55 +54,214 @@ void TransactionHistory::refresh(quint32 accountIndex)
     {
         QWriteLocker locker(&m_lock);
 
-        qDeleteAll(m_tinfo);
-        m_tinfo.clear();
+        clearRows();
 
         quint64 lastTxHeight = 0;
         m_locked = false;
         m_minutesToUnlock = 0;
 
-        m_pimpl->refresh();
-        for (const auto i : m_pimpl->getAll()) {
-            if (i->subaddrAccount() != accountIndex) {
+
+        uint64_t min_height = 0;
+        uint64_t max_height = (uint64_t)-1;
+        uint64_t wallet_height = m_wallet->blockChainHeight();
+        uint32_t account = m_wallet->currentSubaddressAccount();
+
+        // transactions are stored in wallet2:
+        // - confirmed_transfer_details   - out transfers
+        // - unconfirmed_transfer_details - pending out transfers
+        // - payment_details              - input transfers
+
+        // payments are "input transactions";
+        // one input transaction contains only one transfer. e.g. <transaction_id> - <100XMR>
+
+        std::list<std::pair<crypto::hash, tools::wallet2::payment_details>> in_payments;
+        m_wallet2->get_payments(in_payments, min_height, max_height);
+        for (std::list<std::pair<crypto::hash, tools::wallet2::payment_details>>::const_iterator i = in_payments.begin(); i != in_payments.end(); ++i)
+        {
+            const tools::wallet2::payment_details &pd = i->second;
+            if (pd.m_subaddr_index.major != account) {
                 continue;
             }
 
-            m_tinfo.append(new TransactionInfo(i, this));
+            std::string payment_id = epee::string_tools::pod_to_hex(i->first);
+            if (payment_id.substr(16).find_first_not_of('0') == std::string::npos)
+                payment_id = payment_id.substr(0,16);
+
+            auto* t = new TransactionRow();
+            t->m_paymentId = QString::fromStdString(payment_id);
+            t->m_coinbase = pd.m_coinbase;
+            t->m_amount = pd.m_amount;
+            t->m_fee = pd.m_fee;
+            t->m_direction = TransactionRow::Direction_In;
+            t->m_hash = QString::fromStdString(epee::string_tools::pod_to_hex(pd.m_tx_hash));
+            t->m_blockHeight = pd.m_block_height;
+            t->m_description = QString::fromStdString(m_wallet2->get_tx_note(pd.m_tx_hash));
+            t->m_subaddrIndex = { pd.m_subaddr_index.minor };
+            t->m_subaddrAccount = pd.m_subaddr_index.major;
+            t->m_label = QString::fromStdString(m_wallet2->get_subaddress_label(pd.m_subaddr_index));
+            t->m_timestamp = QDateTime::fromSecsSinceEpoch(pd.m_timestamp);
+            t->m_confirmations = (wallet_height > pd.m_block_height) ? wallet_height - pd.m_block_height : 0;
+            t->m_unlockTime = pd.m_unlock_time;
+
+            m_rows.append(t);
+        }
+
+        // confirmed output transactions
+        // one output transaction may contain more than one money transfer, e.g.
+        // <transaction_id>:
+        //    transfer1: 100XMR to <address_1>
+        //    transfer2: 50XMR  to <address_2>
+        //    fee: fee charged per transaction
+        //
 
-            const TransactionInfo *ti = m_tinfo.back();
-            // looking for transactions timestamp scope
-            if (ti->timestamp() >= lastDateTime) {
-                lastDateTime = ti->timestamp();
+        std::list<std::pair<crypto::hash, tools::wallet2::confirmed_transfer_details>> out_payments;
+        m_wallet2->get_payments_out(out_payments, min_height, max_height);
+
+        for (std::list<std::pair<crypto::hash, tools::wallet2::confirmed_transfer_details>>::const_iterator i = out_payments.begin();
+             i != out_payments.end(); ++i) {
+
+            const crypto::hash &hash = i->first;
+            const tools::wallet2::confirmed_transfer_details &pd = i->second;
+            if (pd.m_subaddr_account != account) {
+                continue;
             }
-            if (ti->timestamp() <= firstDateTime) {
-                firstDateTime = ti->timestamp();
+
+            uint64_t change = pd.m_change == (uint64_t)-1 ? 0 : pd.m_change; // change may not be known
+            uint64_t fee = pd.m_amount_in - pd.m_amount_out;
+
+
+            std::string payment_id = epee::string_tools::pod_to_hex(i->second.m_payment_id);
+            if (payment_id.substr(16).find_first_not_of('0') == std::string::npos)
+                payment_id = payment_id.substr(0,16);
+
+
+            auto* t = new TransactionRow();
+            t->m_paymentId = QString::fromStdString(payment_id);
+            t->m_amount = pd.m_amount_in - change - fee;
+            t->m_fee = fee;
+            t->m_direction = TransactionRow::Direction_Out;
+            t->m_hash = QString::fromStdString(epee::string_tools::pod_to_hex(hash));
+            t->m_blockHeight = pd.m_block_height;
+            t->m_description = QString::fromStdString(m_wallet2->get_tx_note(hash));
+            t->m_subaddrAccount = pd.m_subaddr_account;
+            t->m_label = QString::fromStdString(pd.m_subaddr_indices.size() == 1 ? m_wallet2->get_subaddress_label({pd.m_subaddr_account, *pd.m_subaddr_indices.begin()}) : "");
+            t->m_timestamp = QDateTime::fromSecsSinceEpoch(pd.m_timestamp);
+            t->m_confirmations = (wallet_height > pd.m_block_height) ? wallet_height - pd.m_block_height : 0;
+
+            for (uint32_t idx : t->subaddrIndex())
+            {
+                t->m_subaddrIndex.insert(idx);
+            }
+
+            // single output transaction might contain multiple transfers
+            for (auto const &d: pd.m_dests)
+            {
+                Transfer *transfer = new Transfer(d.amount, QString::fromStdString(d.address(m_wallet2->nettype(), pd.m_payment_id)), this);
+                t->m_transfers.append(transfer);
             }
-            quint64 requiredConfirmations = (ti->blockHeight() < ti->unlockTime()) ? ti->unlockTime() - ti->blockHeight() : 10;
-            // store last tx height
-            if (ti->confirmations() < requiredConfirmations && ti->blockHeight() >= lastTxHeight) {
-                lastTxHeight = ti->blockHeight();
-                // TODO: Fetch block time and confirmations needed from wallet2?
-                m_minutesToUnlock = (requiredConfirmations - ti->confirmations()) * 2;
-                m_locked = true;
+            for (auto const &r: pd.m_rings)
+            {
+                Ring *ring = new Ring(QString::fromStdString(epee::string_tools::pod_to_hex(r.first)), cryptonote::relative_output_offsets_to_absolute(r.second), this);
+                t->m_rings.append(ring);
             }
+
+            m_rows.append(t);
         }
-    }
 
-    emit refreshFinished();
+        // unconfirmed output transactions
+        std::list<std::pair<crypto::hash, tools::wallet2::unconfirmed_transfer_details>> upayments_out;
+        m_wallet2->get_unconfirmed_payments_out(upayments_out);
+        for (std::list<std::pair<crypto::hash, tools::wallet2::unconfirmed_transfer_details>>::const_iterator i = upayments_out.begin(); i != upayments_out.end(); ++i) {
+            const tools::wallet2::unconfirmed_transfer_details &pd = i->second;
+            if (pd.m_subaddr_account != account) {
+                continue;
+            }
 
-    if (m_firstDateTime != firstDateTime) {
-        m_firstDateTime = firstDateTime;
-        emit firstDateTimeChanged();
-    }
-    if (m_lastDateTime != lastDateTime) {
-        m_lastDateTime = lastDateTime;
-        emit lastDateTimeChanged();
+            const crypto::hash &hash = i->first;
+            uint64_t amount = pd.m_amount_in;
+            uint64_t fee = amount - pd.m_amount_out;
+            std::string payment_id = epee::string_tools::pod_to_hex(i->second.m_payment_id);
+            if (payment_id.substr(16).find_first_not_of('0') == std::string::npos)
+                payment_id = payment_id.substr(0,16);
+            bool is_failed = pd.m_state == tools::wallet2::unconfirmed_transfer_details::failed;
+
+            auto *t = new TransactionRow();
+            t->m_paymentId = QString::fromStdString(payment_id);
+            t->m_amount = amount - pd.m_change - fee;
+            t->m_fee = fee;
+            t->m_direction = TransactionRow::Direction_Out;
+            t->m_failed = is_failed;
+            t->m_pending = true;
+            t->m_hash = QString::fromStdString(epee::string_tools::pod_to_hex(hash));
+            t->m_description = QString::fromStdString(m_wallet2->get_tx_note(hash));
+            t->m_subaddrAccount = pd.m_subaddr_account;
+            t->m_label = QString::fromStdString(pd.m_subaddr_indices.size() == 1 ? m_wallet2->get_subaddress_label({pd.m_subaddr_account, *pd.m_subaddr_indices.begin()}) : "");
+            t->m_timestamp = QDateTime::fromSecsSinceEpoch(pd.m_timestamp);
+            t->m_confirmations = 0;
+            for (uint32_t idx : t->subaddrIndex())
+            {
+                t->m_subaddrIndex.insert(idx);
+            }
+
+            for (auto const &d: pd.m_dests)
+            {
+                Transfer *transfer = new Transfer(d.amount, QString::fromStdString(d.address(m_wallet2->nettype(), pd.m_payment_id)), this);
+                t->m_transfers.append(transfer);
+            }
+            for (auto const &r: pd.m_rings)
+            {
+                Ring *ring = new Ring(QString::fromStdString(epee::string_tools::pod_to_hex(r.first)), cryptonote::relative_output_offsets_to_absolute(r.second), this);
+                t->m_rings.append(ring);
+            }
+
+            m_rows.append(t);
+        }
+
+
+        // unconfirmed payments (tx pool)
+        std::list<std::pair<crypto::hash, tools::wallet2::pool_payment_details>> upayments;
+        m_wallet2->get_unconfirmed_payments(upayments);
+        for (std::list<std::pair<crypto::hash, tools::wallet2::pool_payment_details>>::const_iterator i = upayments.begin(); i != upayments.end(); ++i) {
+            const tools::wallet2::payment_details &pd = i->second.m_pd;
+            if (pd.m_subaddr_index.major != account) {
+                continue;
+            }
+
+            std::string payment_id = epee::string_tools::pod_to_hex(i->first);
+            if (payment_id.substr(16).find_first_not_of('0') == std::string::npos)
+                payment_id = payment_id.substr(0,16);
+            auto *t = new TransactionRow();
+            t->m_paymentId = QString::fromStdString(payment_id);
+            t->m_amount = pd.m_amount;
+            t->m_direction = TransactionRow::Direction_In;
+            t->m_hash = QString::fromStdString(epee::string_tools::pod_to_hex(pd.m_tx_hash));
+            t->m_blockHeight = pd.m_block_height;
+            t->m_description = QString::fromStdString(m_wallet2->get_tx_note(pd.m_tx_hash));
+            t->m_pending = true;
+            t->m_subaddrIndex = { pd.m_subaddr_index.minor };
+            t->m_subaddrAccount = pd.m_subaddr_index.major;
+            t->m_label = QString::fromStdString(m_wallet2->get_subaddress_label(pd.m_subaddr_index));
+            t->m_timestamp = QDateTime::fromSecsSinceEpoch(pd.m_timestamp);
+            t->m_confirmations = 0;
+
+            m_rows.append(t);
+
+            LOG_PRINT_L1(__FUNCTION__ << ": Unconfirmed payment found " << pd.m_amount);
+        }
     }
+
+    emit refreshFinished();
 }
 
 void TransactionHistory::setTxNote(const QString &txid, const QString &note)
 {
-    m_pimpl->setTxNote(txid.toStdString(), note.toStdString());
+    cryptonote::blobdata txid_data;
+    if(!epee::string_tools::parse_hexstr_to_binbuff(txid.toStdString(), txid_data) || txid_data.size() != sizeof(crypto::hash))
+        return;
+    const crypto::hash htxid = *reinterpret_cast<const crypto::hash*>(txid_data.data());
+
+    m_wallet2->set_tx_note(htxid, note.toStdString());
+    refresh();
     emit txNoteChanged();
 }
 
@@ -109,7 +269,7 @@ quint64 TransactionHistory::count() const
 {
     QReadLocker locker(&m_lock);
 
-    return m_tinfo.count();
+    return m_rows.length();
 }
 
 QDateTime TransactionHistory::firstDateTime() const
@@ -133,8 +293,12 @@ bool TransactionHistory::TransactionHistory::locked() const
 }
 
 
-TransactionHistory::TransactionHistory(Monero::TransactionHistory *pimpl, QObject *parent)
-    : QObject(parent), m_pimpl(pimpl), m_minutesToUnlock(0), m_locked(false)
+TransactionHistory::TransactionHistory(Wallet *wallet, tools::wallet2 *wallet2, QObject *parent)
+    : QObject(parent)
+    , m_wallet(wallet)
+    , m_wallet2(wallet2)
+    , m_minutesToUnlock(0)
+    , m_locked(false)
 {
 #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
     m_firstDateTime = QDate(2014, 4, 18).startOfDay();
@@ -144,22 +308,25 @@ TransactionHistory::TransactionHistory(Monero::TransactionHistory *pimpl, QObjec
     m_lastDateTime = QDateTime::currentDateTime().addDays(1); // tomorrow (guard against jitter and timezones)
 }
 
+void TransactionHistory::clearRows() {
+    qDeleteAll(m_rows);
+    m_rows.clear();
+}
+
 bool TransactionHistory::writeCSV(const QString &path) {
     QString data;
     QReadLocker locker(&m_lock);
 
-    auto transactions = m_pimpl->getAll();
+    auto transactions = m_rows;
 
-    std::sort(transactions.begin(), transactions.end(), [](const Monero::TransactionInfo *info1, const Monero::TransactionInfo *info2){
+    std::sort(m_rows.begin(), m_rows.end(), [](const TransactionRow *info1, const TransactionRow *info2){
         return info1->blockHeight() < info2->blockHeight();
     });
 
-    for (const auto &tx : transactions) {
-        TransactionInfo info(tx, this);
-
+    for (const auto &info : transactions) {
         // collect column data
-        QDateTime timeStamp = info.timestamp();
-        double amount = info.amount();
+        QDateTime timeStamp = info->timestamp();
+        double amount = info->amount();
 
         // calc historical fiat price
         QString fiatAmount;
@@ -176,31 +343,31 @@ bool TransactionHistory::writeCSV(const QString &path) {
             fiatAmount = "\"?\"";
 
         QString direction = QString("");
-        if (info.direction() == TransactionInfo::Direction_In)
+        if (info->direction() == TransactionRow::Direction_In)
             direction = QString("in");
-        else if (info.direction() == TransactionInfo::Direction_Out)
+        else if (info->direction() == TransactionRow::Direction_Out)
             direction = QString("out");
         else
             continue;  // skip TransactionInfo::Direction_Both
 
-        QString displayAmount = info.displayAmount();
-        QString paymentId = info.paymentId();
+        QString displayAmount = info->displayAmount();
+        QString paymentId = info->paymentId();
         if (paymentId == "0000000000000000") {
             paymentId = "";
         }
 
-        QString date = QString("%1T%2Z").arg(info.date(), info.time()); // ISO 8601
+        QString date = QString("%1T%2Z").arg(info->date(), info->time()); // ISO 8601
 
-        QString balanceDelta = WalletManager::displayAmount(info.balanceDelta());
-        if (info.direction() == TransactionInfo::Direction_Out) {
+        QString balanceDelta = WalletManager::displayAmount(info->balanceDelta());
+        if (info->direction() == TransactionRow::Direction_Out) {
             balanceDelta = "-" + balanceDelta;
         }
 
         // format and write
         QString line = QString("\n%1,%2,\"%3\",%4,\"%5\",%6,%7,%8,\"%9\",\"%10\",\"%11\",%12,\"%13\"")
-                .arg(QString::number(info.blockHeight()), QString::number(timeStamp.toSecsSinceEpoch()), date,
-                     QString::number(info.subaddrAccount()), direction, balanceDelta, info.displayAmount(),
-                     info.fee(), info.hash(), info.description(), paymentId, fiatAmount, preferredFiatSymbol);
+                .arg(QString::number(info->blockHeight()), QString::number(timeStamp.toSecsSinceEpoch()), date,
+                     QString::number(info->subaddrAccount()), direction, balanceDelta, info->displayAmount(),
+                     info->fee(), info->hash(), info->description(), paymentId, fiatAmount, preferredFiatSymbol);
         data += line;
     }
 
index 1ee3c147657c215a2fc16fdbc9a779ca1b2c5c6b..c55298d56aa650218e2d5bb6e7cf6be9dde72cf4 100644 (file)
 #include <QReadWriteLock>
 #include <QDateTime>
 
+#include "rows/TransactionRow.h"
+#include "Wallet.h"
+#include "wallet/wallet2.h"
+
 namespace Monero {
 struct TransactionHistory;
 }
@@ -20,24 +24,20 @@ class TransactionInfo;
 class TransactionHistory : public QObject
 {
     Q_OBJECT
-    Q_PROPERTY(int count READ count)
-    Q_PROPERTY(QDateTime firstDateTime READ firstDateTime NOTIFY firstDateTimeChanged)
-    Q_PROPERTY(QDateTime lastDateTime READ lastDateTime NOTIFY lastDateTimeChanged)
-    Q_PROPERTY(int minutesToUnlock READ minutesToUnlock)
-    Q_PROPERTY(bool locked READ locked)
 
 public:
-    Q_INVOKABLE bool transaction(int index, std::function<void (TransactionInfo &)> callback);
-    Q_INVOKABLE TransactionInfo * transaction(const QString &id);
-    TransactionInfo* transaction(int index);
-    Q_INVOKABLE void refresh(quint32 accountIndex);
-    Q_INVOKABLE void setTxNote(const QString &txid, const QString &note);
-    Q_INVOKABLE bool writeCSV(const QString &path);
+    bool transaction(int index, std::function<void (TransactionRow &)> callback);
+    TransactionRow * transaction(const QString &id);
+    TransactionRow* transaction(int index);
+    void refresh();
+    void setTxNote(const QString &txid, const QString &note);
+    bool writeCSV(const QString &path);
     quint64 count() const;
     QDateTime firstDateTime() const;
     QDateTime lastDateTime() const;
     quint64 minutesToUnlock() const;
     bool locked() const;
+    void clearRows();
 
 signals:
     void refreshStarted() const;
@@ -47,13 +47,16 @@ signals:
     void txNoteChanged() const;
 
 private:
-    explicit TransactionHistory(Monero::TransactionHistory * pimpl, QObject *parent = nullptr);
+    explicit TransactionHistory(Wallet *wallet, tools::wallet2 *wallet2, QObject *parent = nullptr);
 
 private:
     friend class Wallet;
     mutable QReadWriteLock m_lock;
-    Monero::TransactionHistory * m_pimpl;
-    mutable QList<TransactionInfo*> m_tinfo;
+
+    Wallet *m_wallet;
+    tools::wallet2 *m_wallet2;
+    QList<TransactionRow*> m_rows;
+
     mutable QDateTime   m_firstDateTime;
     mutable QDateTime   m_lastDateTime;
     mutable int m_minutesToUnlock;
diff --git a/src/libwalletqt/TransactionInfo.cpp b/src/libwalletqt/TransactionInfo.cpp
deleted file mode 100644 (file)
index fe78e91..0000000
+++ /dev/null
@@ -1,202 +0,0 @@
-// SPDX-License-Identifier: BSD-3-Clause
-// SPDX-FileCopyrightText: 2020-2023 The Monero Project
-
-#include "TransactionInfo.h"
-#include "libwalletqt/WalletManager.h"
-#include "Transfer.h"
-#include "Ring.h"
-
-TransactionInfo::Direction TransactionInfo::direction() const
-{
-    return m_direction;
-}
-
-bool TransactionInfo::isPending() const
-{
-    return m_pending;
-}
-
-bool TransactionInfo::isFailed() const
-{
-    return m_failed;
-}
-
-bool TransactionInfo::isCoinbase() const
-{
-    return m_coinbase;
-}
-
-quint64 TransactionInfo::balanceDelta() const
-{
-    if (m_direction == Direction_In) {
-        return m_amount;
-    }
-    else if (m_direction == Direction_Out) {
-        return m_amount + m_fee;
-    }
-    return m_amount;
-}
-
-double TransactionInfo::amount() const
-{
-    // there's no unsigned uint64 for JS, so better use double
-    return displayAmount().toDouble();
-}
-
-quint64 TransactionInfo::atomicAmount() const
-{
-    return m_amount;
-}
-
-QString TransactionInfo::displayAmount() const
-{
-    return WalletManager::displayAmount(m_amount);
-}
-
-quint64 TransactionInfo::atomicFee() const
-{
-    return m_fee;
-}
-
-QString TransactionInfo::fee() const
-{
-    if(m_fee == 0)
-        return "";
-    return WalletManager::displayAmount(m_fee);
-}
-
-quint64 TransactionInfo::blockHeight() const
-{
-    return m_blockHeight;
-}
-
-QString TransactionInfo::description() const
-{
-    return m_description;
-}
-
-QSet<quint32> TransactionInfo::subaddrIndex() const
-{
-    return m_subaddrIndex;
-}
-
-quint32 TransactionInfo::subaddrAccount() const
-{
-    return m_subaddrAccount;
-}
-
-QString TransactionInfo::label() const
-{
-    return m_label;
-}
-
-quint64 TransactionInfo::confirmations() const
-{
-    return m_confirmations;
-}
-
-quint64 TransactionInfo::confirmationsRequired() const
-{
-    return (m_blockHeight < m_unlockTime) ? m_unlockTime - m_blockHeight : 10;
-}
-
-quint64 TransactionInfo::unlockTime() const
-{
-    return m_unlockTime;
-}
-
-QString TransactionInfo::hash() const
-{
-    return m_hash;
-}
-
-QDateTime TransactionInfo::timestamp() const
-{
-    return m_timestamp;
-}
-
-QString TransactionInfo::date() const
-{
-    return timestamp().date().toString(Qt::ISODate);
-}
-
-QString TransactionInfo::time() const
-{
-    return timestamp().time().toString(Qt::ISODate);
-}
-
-QString TransactionInfo::paymentId() const
-{
-    return m_paymentId;
-}
-
-QString TransactionInfo::destinations_formatted() const
-{
-    QString destinations;
-    for (auto const& t: m_transfers) {
-        if (!destinations.isEmpty())
-          destinations += "<br> ";
-        destinations +=  WalletManager::displayAmount(t->amount()) + ": " + t->address();
-    }
-    return destinations;
-}
-
-QList<QString> TransactionInfo::destinations() const
-{
-    QList<QString> dests;
-    for (auto const& t: m_transfers) {
-        dests.append(t->address());
-    }
-    return dests;
-}
-
-QList<Transfer*> TransactionInfo::transfers() const {
-    return m_transfers;
-}
-
-QString TransactionInfo::rings_formatted() const
-{
-    QString rings;
-    for (auto const& r: m_rings) {
-        rings += r->keyImage() + ": \n";
-        for (uint64_t m : r->ringMembers()){
-            rings += QString::number(m) + " ";
-        }
-        rings += "\n\n";
-    }
-    return rings;
-}
-
-TransactionInfo::TransactionInfo(const Monero::TransactionInfo *pimpl, QObject *parent)
-    : QObject(parent)
-    , m_amount(pimpl->amount())
-    , m_blockHeight(pimpl->blockHeight())
-    , m_description(QString::fromStdString(pimpl->description()))
-    , m_confirmations(pimpl->confirmations())
-    , m_direction(static_cast<Direction>(pimpl->direction()))
-    , m_failed(pimpl->isFailed())
-    , m_fee(pimpl->fee())
-    , m_hash(QString::fromStdString(pimpl->hash()))
-    , m_label(QString::fromStdString(pimpl->label()))
-    , m_paymentId(QString::fromStdString(pimpl->paymentId()))
-    , m_pending(pimpl->isPending())
-    , m_subaddrAccount(pimpl->subaddrAccount())
-    , m_timestamp(QDateTime::fromSecsSinceEpoch(pimpl->timestamp()))
-    , m_unlockTime(pimpl->unlockTime())
-    , m_coinbase(pimpl->isCoinbase())
-{
-    for (auto const &t: pimpl->transfers())
-    {
-        Transfer *transfer = new Transfer(t.amount, QString::fromStdString(t.address), this);
-        m_transfers.append(transfer);
-    }
-    for (auto const &r: pimpl->rings())
-    {
-        Ring *ring = new Ring(QString::fromStdString(r.first), r.second, this);
-        m_rings.append(ring);
-    }
-    for (uint32_t i : pimpl->subaddrIndex())
-    {
-        m_subaddrIndex.insert(i);
-    }
-}
index f3d961baec40445b25a04612bdba16ed25fc692b..8c18609c869709a6178f99f3253eb2d86384c595 100644 (file)
@@ -12,7 +12,7 @@ class Transfer : public QObject
 {
     Q_OBJECT
 
-private:
+public:
     explicit Transfer(uint64_t _amount, QString _address,  QObject *parent = 0)
             : QObject(parent), m_amount(_amount), m_address(std::move(_address)) {};
 private:
index 9b6117d6edfb52974068a8edf353e77f544e81c2..87f5e9d259fc30442b01509121c9666f24b6cc7f 100644 (file)
@@ -32,21 +32,21 @@ namespace {
 Wallet::Wallet(Monero::Wallet *wallet, QObject *parent)
         : QObject(parent)
         , m_walletImpl(wallet)
-        , m_history(new TransactionHistory(m_walletImpl->history(), this))
+        , m_history(new TransactionHistory(this, wallet->getWallet(), this))
         , m_historyModel(nullptr)
-        , m_addressBook(new AddressBook(m_walletImpl->addressBook(), this))
+        , m_addressBook(new AddressBook(this, wallet->getWallet(), this))
         , m_addressBookModel(nullptr)
         , m_daemonBlockChainHeight(0)
         , m_daemonBlockChainTargetHeight(0)
         , m_connectionStatus(Wallet::ConnectionStatus_Disconnected)
         , m_currentSubaddressAccount(0)
         , m_subaddress(new Subaddress(this, wallet->getWallet(), this))
-        , m_subaddressAccount(new SubaddressAccount(m_walletImpl->subaddressAccount(), this))
+        , m_subaddressAccount(new SubaddressAccount(this, wallet->getWallet(), this))
         , m_refreshNow(false)
         , m_refreshEnabled(false)
         , m_scheduler(this)
         , m_useSSL(true)
-        , m_coins(new Coins(m_walletImpl->coins(), this))
+        , m_coins(new Coins(this, wallet->getWallet(), this))
         , m_storeTimer(new QTimer(this))
 {
     m_walletListener = new WalletListenerImpl(this);
@@ -71,7 +71,7 @@ Wallet::Wallet(Monero::Wallet *wallet, QObject *parent)
     }
 
     connect(this->history(), &TransactionHistory::txNoteChanged, [this]{
-        this->history()->refresh(this->currentSubaddressAccount());
+        this->history()->refresh();
     });
 
     connect(this, &Wallet::refreshed, this, &Wallet::onRefreshed);
@@ -185,8 +185,8 @@ void Wallet::switchSubaddressAccount(quint32 accountIndex) {
             qWarning() << "failed to set " << ATTRIBUTE_SUBADDRESS_ACCOUNT << " cache attribute";
         }
         m_subaddress->refresh(m_currentSubaddressAccount);
-        m_history->refresh(m_currentSubaddressAccount);
-        m_coins->refresh(m_currentSubaddressAccount);
+        m_history->refresh();
+        m_coins->refresh();
         this->subaddressModel()->setCurrentSubaddressAccount(m_currentSubaddressAccount);
         this->coinsModel()->setCurrentSubaddressAccount(m_currentSubaddressAccount);
         this->updateBalance();
@@ -453,8 +453,8 @@ void Wallet::onRefreshed(bool success, const QString &message) {
 }
 
 void Wallet::refreshModels() {
-    m_history->refresh(this->currentSubaddressAccount());
-    m_coins->refresh(this->currentSubaddressAccount());
+    m_history->refresh();
+    m_coins->refresh();
     bool r = this->subaddress()->refresh(this->currentSubaddressAccount());
 
     if (!r) {
@@ -776,8 +776,8 @@ void Wallet::onTransactionCommitted(bool success, PendingTransaction *tx, const
     // Store wallet immediately, so we don't risk losing tx key if wallet crashes
     this->storeSafer();
 
-    this->history()->refresh(this->currentSubaddressAccount());
-    this->coins()->refresh(this->currentSubaddressAccount());
+    this->history()->refresh();
+    this->coins()->refresh();
     this->updateBalance();
 
     if (!success) {
diff --git a/src/libwalletqt/rows/AccountRow.cpp b/src/libwalletqt/rows/AccountRow.cpp
new file mode 100644 (file)
index 0000000..591402a
--- /dev/null
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: BSD-3-Clause
+// SPDX-FileCopyrightText: 2020-2023 The Monero Project
+
+#include "AccountRow.h"
+#include "WalletManager.h"
+
+qsizetype AccountRow::getRow() const {
+    return m_row;
+}
+
+const QString& AccountRow::getAddress() const {
+    return m_address;
+}
+
+const QString& AccountRow::getLabel() const {
+    return m_label;
+}
+
+QString AccountRow::getBalance() const {
+    return WalletManager::displayAmount(m_balance);
+}
+
+QString AccountRow::getUnlockedBalance() const {
+    return WalletManager::displayAmount(m_unlockedBalance);
+}
\ No newline at end of file
diff --git a/src/libwalletqt/rows/AccountRow.h b/src/libwalletqt/rows/AccountRow.h
new file mode 100644 (file)
index 0000000..46283fd
--- /dev/null
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: BSD-3-Clause
+// SPDX-FileCopyrightText: 2020-2023 The Monero Project
+
+#ifndef FEATHER_ACCOUNTROW_H
+#define FEATHER_ACCOUNTROW_H
+
+#include <QObject>
+
+class AccountRow : public QObject
+{
+Q_OBJECT
+
+public:
+    AccountRow(QObject *parent, qsizetype row, const QString& address, const QString &label, uint64_t balance, uint64_t unlockedBalance)
+            : QObject(parent)
+            , m_row(row)
+            , m_address(address)
+            , m_label(label)
+            , m_balance(balance)
+            , m_unlockedBalance(unlockedBalance) {}
+
+    qsizetype getRow() const;
+    const QString& getAddress() const;
+    const QString& getLabel() const;
+    QString getBalance() const;
+    QString getUnlockedBalance() const;
+
+private:
+    qsizetype m_row;
+    QString m_address;
+    QString m_label;
+    uint64_t m_balance;
+    uint64_t m_unlockedBalance;
+};
+
+#endif //FEATHER_ACCOUNTROW_H
similarity index 60%
rename from src/libwalletqt/CoinsInfo.cpp
rename to src/libwalletqt/rows/CoinsInfo.cpp
index 925d6c6f7f5e63fb408311f35883c0aa5a7cec0a..2c00364877dfadbb0b921e53a5201cb66a8d7867 100644 (file)
@@ -74,7 +74,15 @@ QString CoinsInfo::address() const {
 
 QString CoinsInfo::addressLabel() const {
     if (m_subaddrIndex == 0) {
-        return m_coinbase ? "Coinbase" : "Change";
+        if (m_coinbase) {
+            return "Coinbase";
+        }
+        if (m_change) {
+            return "Change";
+        }
+        if (m_addressLabel == "Primary account") {
+            return "Primary address";
+        }
     }
 
     return m_addressLabel;
@@ -108,29 +116,28 @@ QString CoinsInfo::description() const {
     return m_description;
 }
 
-CoinsInfo::CoinsInfo(const Monero::CoinsInfo *pimpl, QObject *parent)
+bool CoinsInfo::change() const {
+    return m_change;
+}
+
+CoinsInfo::CoinsInfo(QObject *parent)
         : QObject(parent)
-        , m_blockHeight(pimpl->blockHeight())
-        , m_hash(QString::fromStdString(pimpl->hash()))
-        , m_internalOutputIndex(pimpl->internalOutputIndex())
-        , m_globalOutputIndex(pimpl->globalOutputIndex())
-        , m_spent(pimpl->spent())
-        , m_frozen(pimpl->frozen())
-        , m_spentHeight(pimpl->spentHeight())
-        , m_amount(pimpl->amount())
-        , m_rct(pimpl->rct())
-        , m_keyImageKnown(pimpl->keyImageKnown())
-        , m_pkIndex(pimpl->pkIndex())
-        , m_subaddrIndex(pimpl->subaddrIndex())
-        , m_subaddrAccount(pimpl->subaddrAccount())
-        , m_address(QString::fromStdString(pimpl->address()))
-        , m_addressLabel(QString::fromStdString(pimpl->addressLabel()))
-        , m_keyImage(QString::fromStdString(pimpl->keyImage()))
-        , m_unlockTime(pimpl->unlockTime())
-        , m_unlocked(pimpl->unlocked())
-        , m_pubKey(QString::fromStdString(pimpl->pubKey()))
-        , m_coinbase(pimpl->coinbase())
-        , m_description(QString::fromStdString(pimpl->description()))
+        , 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)
 {
 
 }
similarity index 58%
rename from src/libwalletqt/CoinsInfo.h
rename to src/libwalletqt/rows/CoinsInfo.h
index 42c39db33b74d3a57c62eb5c72e217b26452579a..a68fd1bc28f72c9315df2e58d832a3179a85ea42 100644 (file)
@@ -14,28 +14,6 @@ class Coins;
 class CoinsInfo : public QObject
 {
 Q_OBJECT
-    Q_PROPERTY(quint64 blockHeight READ blockHeight)
-    Q_PROPERTY(QString hash READ hash)
-    Q_PROPERTY(quint64 internalOutputIndex READ internalOutputIndex)
-    Q_PROPERTY(quint64 globalOutputIndex READ globalOutputIndex)
-    Q_PROPERTY(bool spent READ spent)
-    Q_PROPERTY(bool frozen READ frozen)
-    Q_PROPERTY(quint64 spentHeight READ spentHeight)
-    Q_PROPERTY(quint64 amount READ amount)
-    Q_PROPERTY(QString displayAmount READ displayAmount)
-    Q_PROPERTY(bool rct READ rct)
-    Q_PROPERTY(bool keyImageKnown READ keyImageKnown)
-    Q_PROPERTY(quint64 pkIndex READ pkIndex)
-    Q_PROPERTY(quint32 subaddrIndex READ subaddrIndex)
-    Q_PROPERTY(quint32 subaddrAccount READ subaddrAccount)
-    Q_PROPERTY(QString address READ address)
-    Q_PROPERTY(QString addressLabel READ addressLabel)
-    Q_PROPERTY(QString keyImage READ keyImage)
-    Q_PROPERTY(quint64 unlockTime READ unlockTime)
-    Q_PROPERTY(bool unlocked READ unlocked)
-    Q_PROPERTY(QString pubKey READ pubKey)
-    Q_PROPERTY(bool coinbase READ coinbase)
-    Q_PROPERTY(QString description READ description)
 
 public:
     quint64 blockHeight() const;
@@ -60,11 +38,13 @@ public:
     QString pubKey() const;
     bool coinbase() const;
     QString description() const;
+    bool change() const;
 
     void setUnlocked(bool unlocked);
 
 private:
-    explicit CoinsInfo(const Monero::CoinsInfo *pimpl, QObject *parent = nullptr);
+    explicit CoinsInfo(QObject *parent);
+
 private:
     friend class Coins;
 
@@ -89,6 +69,7 @@ private:
     QString m_pubKey;
     bool m_coinbase;
     QString m_description;
+    bool m_change;
 };
 
 #endif //FEATHER_COINSINFO_H
diff --git a/src/libwalletqt/rows/ContactRow.cpp b/src/libwalletqt/rows/ContactRow.cpp
new file mode 100644 (file)
index 0000000..e31957a
--- /dev/null
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: BSD-3-Clause
+// SPDX-FileCopyrightText: 2020-2023 The Monero Project
+
+#include "ContactRow.h"
+
+qsizetype ContactRow::getRow() const {
+    return m_row;
+}
+
+const QString& ContactRow::getAddress() const {
+    return m_address;
+}
+
+const QString& ContactRow::getLabel() const {
+    return m_label;
+}
\ No newline at end of file
diff --git a/src/libwalletqt/rows/ContactRow.h b/src/libwalletqt/rows/ContactRow.h
new file mode 100644 (file)
index 0000000..901017a
--- /dev/null
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: BSD-3-Clause
+// SPDX-FileCopyrightText: 2020-2023 The Monero Project
+
+#ifndef FEATHER_CONTACTROW_H
+#define FEATHER_CONTACTROW_H
+
+#include <QObject>
+
+class ContactRow : public QObject
+{
+    Q_OBJECT
+
+public:
+    ContactRow(QObject *parent, qsizetype row, const QString& address, const QString &label)
+            : QObject(parent)
+            , m_row(row)
+            , m_address(address)
+            , m_label(label) {}
+
+    qsizetype getRow() const;
+    const QString& getAddress() const;
+    const QString& getLabel() const;
+
+private:
+    qsizetype m_row;
+    QString m_address;
+    QString m_label;
+};
+
+
+#endif //FEATHER_CONTACTROW_H
diff --git a/src/libwalletqt/rows/TransactionRow.cpp b/src/libwalletqt/rows/TransactionRow.cpp
new file mode 100644 (file)
index 0000000..e2f7465
--- /dev/null
@@ -0,0 +1,183 @@
+// SPDX-License-Identifier: BSD-3-Clause
+// SPDX-FileCopyrightText: 2020-2023 The Monero Project
+
+#include "TransactionRow.h"
+#include "WalletManager.h"
+#include "Transfer.h"
+#include "Ring.h"
+
+TransactionRow::TransactionRow()
+        : m_direction(TransactionRow::Direction_Out)
+        , m_pending(false)
+        , m_failed(false)
+        , m_coinbase(false)
+        , m_amount(0)
+        , m_fee(0)
+        , m_blockHeight(0)
+        , m_subaddrAccount(0)
+        , m_confirmations(0)
+        , m_unlockTime(0)
+        , m_confirmationsRequired(0)
+{
+}
+
+TransactionRow::Direction TransactionRow::direction() const
+{
+    return m_direction;
+}
+
+bool TransactionRow::isPending() const
+{
+    return m_pending;
+}
+
+bool TransactionRow::isFailed() const
+{
+    return m_failed;
+}
+
+bool TransactionRow::isCoinbase() const
+{
+    return m_coinbase;
+}
+
+quint64 TransactionRow::balanceDelta() const
+{
+    if (m_direction == Direction_In) {
+        return m_amount;
+    }
+    else if (m_direction == Direction_Out) {
+        return m_amount + m_fee;
+    }
+    return m_amount;
+}
+
+double TransactionRow::amount() const
+{
+    // there's no unsigned uint64 for JS, so better use double
+    return displayAmount().toDouble();
+}
+
+quint64 TransactionRow::atomicAmount() const
+{
+    return m_amount;
+}
+
+QString TransactionRow::displayAmount() const
+{
+    return WalletManager::displayAmount(m_amount);
+}
+
+quint64 TransactionRow::atomicFee() const
+{
+    return m_fee;
+}
+
+QString TransactionRow::fee() const
+{
+    if(m_fee == 0)
+        return "";
+    return WalletManager::displayAmount(m_fee);
+}
+
+quint64 TransactionRow::blockHeight() const
+{
+    return m_blockHeight;
+}
+
+QString TransactionRow::description() const
+{
+    return m_description;
+}
+
+QSet<quint32> TransactionRow::subaddrIndex() const
+{
+    return m_subaddrIndex;
+}
+
+quint32 TransactionRow::subaddrAccount() const
+{
+    return m_subaddrAccount;
+}
+
+QString TransactionRow::label() const
+{
+    return m_label;
+}
+
+quint64 TransactionRow::confirmations() const
+{
+    return m_confirmations;
+}
+
+quint64 TransactionRow::confirmationsRequired() const
+{
+    return (m_blockHeight < m_unlockTime) ? m_unlockTime - m_blockHeight : 10;
+}
+
+quint64 TransactionRow::unlockTime() const
+{
+    return m_unlockTime;
+}
+
+QString TransactionRow::hash() const
+{
+    return m_hash;
+}
+
+QDateTime TransactionRow::timestamp() const
+{
+    return m_timestamp;
+}
+
+QString TransactionRow::date() const
+{
+    return timestamp().date().toString(Qt::ISODate);
+}
+
+QString TransactionRow::time() const
+{
+    return timestamp().time().toString(Qt::ISODate);
+}
+
+QString TransactionRow::paymentId() const
+{
+    return m_paymentId;
+}
+
+QString TransactionRow::destinations_formatted() const
+{
+    QString destinations;
+    for (auto const& t: m_transfers) {
+        if (!destinations.isEmpty())
+            destinations += "<br> ";
+        destinations += WalletManager::displayAmount(t->amount()) + ": " + t->address();
+    }
+    return destinations;
+}
+
+QList<QString> TransactionRow::destinations() const
+{
+    QList<QString> dests;
+    for (auto const& t: m_transfers) {
+        dests.append(t->address());
+    }
+    return dests;
+}
+
+QList<Transfer*> TransactionRow::transfers() const {
+    return m_transfers;
+}
+
+QString TransactionRow::rings_formatted() const
+{
+    QString rings;
+    for (auto const& r: m_rings) {
+        rings += r->keyImage() + ": \n";
+        for (uint64_t m : r->ringMembers()){
+            rings += QString::number(m) + " ";
+        }
+        rings += "\n\n";
+    }
+    return rings;
+}
\ No newline at end of file
similarity index 54%
rename from src/libwalletqt/TransactionInfo.h
rename to src/libwalletqt/rows/TransactionRow.h
index 9e496c4d2182b09698ceb138afc4fe133cd2b8dc..06030f6ed3e140b541ef300c8869676124993a4e 100644 (file)
@@ -1,48 +1,24 @@
 // SPDX-License-Identifier: BSD-3-Clause
 // SPDX-FileCopyrightText: 2020-2023 The Monero Project
 
-#ifndef TRANSACTIONINFO_H
-#define TRANSACTIONINFO_H
-
-#include <wallet/api/wallet2_api.h>
-#include <QObject>
-#include <QDateTime>
-#include <QSet>
+#ifndef FEATHER_TRANSACTIONROW_H
+#define FEATHER_TRANSACTIONROW_H
 
 class Transfer;
 class Ring;
 
-class TransactionInfo : public QObject
+#include <QObject>
+#include <QSet>
+#include <QDateTime>
+
+class TransactionRow : public QObject
 {
     Q_OBJECT
-    Q_PROPERTY(Direction direction READ direction)
-    Q_PROPERTY(bool isPending READ isPending)
-    Q_PROPERTY(bool isFailed READ isFailed)
-    Q_PROPERTY(bool isCoinbase READ isCoinbase)
-    Q_PROPERTY(double amount READ amount)
-    Q_PROPERTY(quint64 atomicAmount READ atomicAmount)
-    Q_PROPERTY(QString displayAmount READ displayAmount)
-    Q_PROPERTY(QString fee READ fee)
-    Q_PROPERTY(quint64 blockHeight READ blockHeight)
-    Q_PROPERTY(QString description READ description)
-    Q_PROPERTY(QSet<quint32> subaddrIndex READ subaddrIndex)
-    Q_PROPERTY(quint32 subaddrAccount READ subaddrAccount)
-    Q_PROPERTY(QString label READ label)
-    Q_PROPERTY(quint64 confirmations READ confirmations)
-    Q_PROPERTY(quint64 confirmationsRequired READ confirmationsRequired)
-    Q_PROPERTY(quint64 unlockTime READ unlockTime)
-    Q_PROPERTY(QString hash READ hash)
-    Q_PROPERTY(QDateTime timestamp READ timestamp)
-    Q_PROPERTY(QString date READ date)
-    Q_PROPERTY(QString time READ time)
-    Q_PROPERTY(QString paymentId READ paymentId)
-    Q_PROPERTY(QString destinations_formatted READ destinations_formatted)
-    Q_PROPERTY(QString rings_formatted READ rings_formatted)
 
 public:
     enum Direction {
-        Direction_In  =  Monero::TransactionInfo::Direction_In,
-        Direction_Out =  Monero::TransactionInfo::Direction_Out,
+        Direction_In  =  0,
+        Direction_Out =  1,
         Direction_Both // invalid direction value, used for filtering
     };
 
@@ -80,7 +56,10 @@ public:
     QString rings_formatted() const;
 
 private:
-    explicit TransactionInfo(const Monero::TransactionInfo *pimpl, QObject *parent = nullptr);
+    explicit TransactionRow();
+
+//    TransactionRow(const Monero::TransactionInfo *pimpl, QObject *parent = nullptr);
+
 private:
     friend class TransactionHistory;
     mutable QList<Transfer*> m_transfers;
@@ -104,4 +83,5 @@ private:
     bool m_coinbase;
 };
 
-#endif // TRANSACTIONINFO_H
+
+#endif //FEATHER_TRANSACTIONROW_H
index 214daa5539888c19ebec9cc6b200ba73292e4ffc..fb66425351c50505d383c68313967759319fb3ac 100644 (file)
@@ -70,12 +70,12 @@ QVariant AddressBookModel::data(const QModelIndex &index, int role) const
 {
     QVariant result;
 
-    bool found = m_addressBook->getRow(index.row(), [this, &result, &role, &index](const AddressBookInfo &row) {
+    bool found = m_addressBook->getRow(index.row(), [this, &result, &role, &index](const ContactRow &row) {
         if (role == Qt::DisplayRole || role == Qt::EditRole || role == Qt::UserRole) {
             switch (index.column()) {
                 case Address:
                 {
-                    QString address = row.address();
+                    QString address = row.getAddress();
                     if (!m_showFullAddresses && role != Qt::UserRole) {
                         address = Utils::displayAddress(address);
                     }
@@ -83,7 +83,7 @@ QVariant AddressBookModel::data(const QModelIndex &index, int role) const
                     break;
                 }
                 case Description:
-                    result = row.description();
+                    result = row.getLabel();
                     break;
                 default:
                     qCritical() << "Invalid column" << index.column();
index e69f51a5265863cd7cc18b2569181a4ded437d56..27bb1dff09fa83db84958ab35802967af7a330c4 100644 (file)
@@ -2,7 +2,7 @@
 // SPDX-FileCopyrightText: 2020-2023 The Monero Project
 
 #include "CoinsModel.h"
-#include "CoinsInfo.h"
+#include "libwalletqt/rows/CoinsInfo.h"
 #include "Coins.h"
 #include "constants.h"
 #include "utils/ColorScheme.h"
index 16e3a9dc1a20875ddf60a920f72afed9bf5ece61..92077c540e418464083b5bc423d2399f9b9a5725 100644 (file)
@@ -3,7 +3,7 @@
 
 #include "CoinsProxyModel.h"
 #include "CoinsModel.h"
-#include "libwalletqt/CoinsInfo.h"
+#include "libwalletqt/rows/CoinsInfo.h"
 
 CoinsProxyModel::CoinsProxyModel(QObject *parent, Coins *coins)
         : QSortFilterProxyModel(parent)
index 4caefedb664f6d95e96d03c558bd6c3a4de86587..9fe311df6b5130b1092eb18f42cd07ee56a7ee67 100644 (file)
@@ -4,7 +4,6 @@
 #include "HistoryView.h"
 
 #include "TransactionHistoryProxyModel.h"
-#include "libwalletqt/TransactionInfo.h"
 #include "utils/Utils.h"
 
 #include <QHeaderView>
@@ -71,7 +70,7 @@ TransactionHistoryModel* HistoryView::sourceModel()
     return dynamic_cast<TransactionHistoryModel *>(m_model->sourceModel());
 }
 
-TransactionInfo* HistoryView::currentEntry()
+TransactionRow* HistoryView::currentEntry()
 {
     QModelIndexList list = selectionModel()->selectedRows();
     if (list.size() == 1) {
@@ -199,7 +198,7 @@ void HistoryView::resetViewToDefaults()
 }
 
 void HistoryView::keyPressEvent(QKeyEvent *event) {
-    TransactionInfo* tx = this->currentEntry();
+    TransactionRow* tx = this->currentEntry();
 
     if (event->matches(QKeySequence::Copy) && tx) {
         Utils::copyToClipboard(tx->hash());
index 5eea566b3b763294a44974f9dc58992da040ae0b..bab00f35d387f2548bd4aa4102aa4abc9b81cddd 100644 (file)
@@ -18,7 +18,7 @@ class HistoryView : public QTreeView
 public:
     explicit HistoryView(QWidget* parent = nullptr);
     void setHistoryModel(TransactionHistoryProxyModel *model);
-    TransactionInfo* currentEntry();
+    TransactionRow* currentEntry();
 
     void setSearchMode(bool mode);
     QByteArray viewState() const;
index 138d684b6a9afc8640e0c31e4328e865bdb9794e..f0cdff7f8eb72dff71d41ae3562f8db61e5e2135 100644 (file)
@@ -8,6 +8,7 @@
 #include "utils/Utils.h"
 
 #include "libwalletqt/WalletManager.h"
+#include "rows/AccountRow.h"
 
 SubaddressAccountModel::SubaddressAccountModel(QObject *parent, SubaddressAccount *subaddressAccount)
     : QAbstractTableModel(parent)
@@ -49,7 +50,7 @@ QVariant SubaddressAccountModel::data(const QModelIndex &index, int role) const
 
     QVariant result;
 
-    bool found = m_subaddressAccount->getRow(index.row(), [this, &index, &result, &role](const Monero::SubaddressAccountRow &row) {
+    bool found = m_subaddressAccount->getRow(index.row(), [this, &index, &result, &role](const AccountRow &row) {
         if (role == Qt::DisplayRole || role == Qt::EditRole || role == Qt::UserRole) {
             result = parseSubaddressAccountRow(row, index, role);
         }
@@ -72,7 +73,7 @@ QVariant SubaddressAccountModel::data(const QModelIndex &index, int role) const
     return result;
 }
 
-QVariant SubaddressAccountModel::parseSubaddressAccountRow(const Monero::SubaddressAccountRow &row,
+QVariant SubaddressAccountModel::parseSubaddressAccountRow(const AccountRow &row,
                                                            const QModelIndex &index, int role) const
 {
     switch (index.column()) {
@@ -82,19 +83,19 @@ QVariant SubaddressAccountModel::parseSubaddressAccountRow(const Monero::Subaddr
             }
             return QString("#%1").arg(QString::number(index.row()));
         case Address:
-            return QString::fromStdString(row.getAddress());
+            return row.getAddress();
         case Label:
-            return QString::fromStdString(row.getLabel());
+            return row.getLabel();
         case Balance:
             if (role == Qt::UserRole) {
-                return WalletManager::amountFromString(QString::fromStdString(row.getBalance()));
+                return WalletManager::amountFromString(row.getBalance());
             }
-            return QString::fromStdString(row.getBalance());
+            return row.getBalance();
         case UnlockedBalance:
             if (role == Qt::UserRole) {
-                return WalletManager::amountFromString(QString::fromStdString(row.getUnlockedBalance()));
+                return WalletManager::amountFromString(row.getUnlockedBalance());
             }
-            return QString::fromStdString(row.getUnlockedBalance());
+            return row.getUnlockedBalance();
         default:
             return QVariant();
     }
@@ -154,8 +155,7 @@ Qt::ItemFlags SubaddressAccountModel::flags(const QModelIndex &index) const
     return QAbstractTableModel::flags(index);
 }
 
-Monero::SubaddressAccountRow* SubaddressAccountModel::entryFromIndex(const QModelIndex &index) const {
-    Q_ASSERT(index.isValid() && index.row() < m_subaddressAccount->count());
+AccountRow* SubaddressAccountModel::entryFromIndex(const QModelIndex &index) const {
     return m_subaddressAccount->row(index.row());
 }
 
index 7ce0bbcaa85a5b4dd547f706161f10584ce2d638..98b27054dee903f5fca2c242c3c35eeb9500fbd0 100644 (file)
@@ -8,6 +8,8 @@
 #include <QAbstractTableModel>
 #include <QSortFilterProxyModel>
 
+#include "rows/AccountRow.h"
+
 class SubaddressAccount;
 
 class SubaddressAccountModel : public QAbstractTableModel
@@ -34,14 +36,14 @@ public:
 
     bool setData(const QModelIndex &index, const QVariant &value, int role) override;
 
-    Monero::SubaddressAccountRow* entryFromIndex(const QModelIndex &index) const;
+    AccountRow* entryFromIndex(const QModelIndex &index) const;
 
 public slots:
     void startReset();
     void endReset();
 
 private:
-    QVariant parseSubaddressAccountRow(const Monero::SubaddressAccountRow &row, const QModelIndex &index, int role) const;
+    QVariant parseSubaddressAccountRow(const AccountRow &row, const QModelIndex &index, int role) const;
 
     SubaddressAccount *m_subaddressAccount;
 };
index 0d69012417d9c6ff46113236dcb8b314ab0cdc63..cd7c0024a5c5717fc24c083b1ba8c8fc06a36d22 100644 (file)
@@ -3,13 +3,13 @@
 
 #include "TransactionHistoryModel.h"
 #include "TransactionHistory.h"
-#include "TransactionInfo.h"
 #include "constants.h"
 #include "utils/config.h"
 #include "utils/ColorScheme.h"
 #include "utils/Icons.h"
 #include "utils/AppData.h"
 #include "utils/Utils.h"
+#include "libwalletqt/rows/TransactionRow.h"
 
 TransactionHistoryModel::TransactionHistoryModel(QObject *parent)
     : QAbstractTableModel(parent),
@@ -34,7 +34,7 @@ TransactionHistory *TransactionHistoryModel::transactionHistory() const {
     return m_transactionHistory;
 }
 
-TransactionInfo* TransactionHistoryModel::entryFromIndex(const QModelIndex &index) const {
+TransactionRow* TransactionHistoryModel::entryFromIndex(const QModelIndex &index) const {
     Q_ASSERT(index.isValid() && index.row() < m_transactionHistory->count());
     return m_transactionHistory->transaction(index.row());
 }
@@ -65,7 +65,7 @@ QVariant TransactionHistoryModel::data(const QModelIndex &index, int role) const
 
     QVariant result;
 
-    bool found = m_transactionHistory->transaction(index.row(), [this, &index, &result, &role](const TransactionInfo &tInfo) {
+    bool found = m_transactionHistory->transaction(index.row(), [this, &index, &result, &role](const TransactionRow &tInfo) {
         if(role == Qt::DisplayRole || role == Qt::EditRole || role == Qt::UserRole) {
             result = parseTransactionInfo(tInfo, index.column(), role);
         }
@@ -117,7 +117,7 @@ QVariant TransactionHistoryModel::data(const QModelIndex &index, int role) const
                 case Column::FiatAmount:
                 case Column::Amount:
                 {
-                    if (tInfo.direction() == TransactionInfo::Direction_Out) {
+                    if (tInfo.direction() == TransactionRow::Direction_Out) {
                         result = QVariant(QColor("#BC1E1E"));
                     }
                 }
@@ -139,7 +139,7 @@ QVariant TransactionHistoryModel::data(const QModelIndex &index, int role) const
     return result;
 }
 
-QVariant TransactionHistoryModel::parseTransactionInfo(const TransactionInfo &tInfo, int column, int role) const
+QVariant TransactionHistoryModel::parseTransactionInfo(const TransactionRow &tInfo, int column, int role) const
 {
     switch (column)
     {
@@ -159,7 +159,7 @@ QVariant TransactionHistoryModel::parseTransactionInfo(const TransactionInfo &tI
                 return tInfo.balanceDelta();
             }
             QString amount = QString::number(tInfo.balanceDelta() / constants::cdiv, 'f', conf()->get(Config::amountPrecision).toInt());
-            amount = (tInfo.direction() == TransactionInfo::Direction_Out) ? "-" + amount : "+" + amount;
+            amount = (tInfo.direction() == TransactionRow::Direction_Out) ? "-" + amount : "+" + amount;
             return amount;
         }
         case Column::TxID: {
@@ -227,7 +227,7 @@ bool TransactionHistoryModel::setData(const QModelIndex &index, const QVariant &
         switch (index.column()) {
             case Column::Description:
             {
-                m_transactionHistory->transaction(index.row(), [this, &hash, &value](const TransactionInfo &tInfo){
+                m_transactionHistory->transaction(index.row(), [this, &hash, &value](const TransactionRow &tInfo){
                     hash = tInfo.hash();
                 });
                 m_transactionHistory->setTxNote(hash, value.toString());
index 582c57ccc1b855fa18750eedeb729894c1b93f5c..a55f235de5fb70687e2b48fee2bd5da9b9b0bade 100644 (file)
@@ -8,7 +8,7 @@
 #include <QIcon>
 
 class TransactionHistory;
-class TransactionInfo;
+class TransactionRow;
 
 /**
  * @brief The TransactionHistoryModel class - read-only table model for Transaction History
@@ -33,7 +33,7 @@ public:
     explicit TransactionHistoryModel(QObject * parent = nullptr);
     void setTransactionHistory(TransactionHistory * th);
     TransactionHistory * transactionHistory() const;
-    TransactionInfo* entryFromIndex(const QModelIndex& index) const;
+    TransactionRow* entryFromIndex(const QModelIndex& index) const;
 
     int rowCount(const QModelIndex & parent = QModelIndex()) const override;
     int columnCount(const QModelIndex &parent = QModelIndex()) const override;
@@ -47,7 +47,7 @@ signals:
     void transactionHistoryChanged();
 
 private:
-    QVariant parseTransactionInfo(const TransactionInfo &tInfo, int column, int role) const;
+    QVariant parseTransactionInfo(const TransactionRow &tInfo, int column, int role) const;
 
     TransactionHistory * m_transactionHistory;
 };
index e905c62ced1ddef567494d743e4f76ded853d1eb..831037338da1abfb1aa3c090632c000d51bbb4b5 100644 (file)
@@ -4,7 +4,7 @@
 #include "TransactionHistoryProxyModel.h"
 #include "TransactionHistoryModel.h"
 
-#include "libwalletqt/TransactionInfo.h"
+#include "libwalletqt/rows/TransactionRow.h"
 
 TransactionHistoryProxyModel::TransactionHistoryProxyModel(Wallet *wallet, QObject *parent)
         : QSortFilterProxyModel(parent)
@@ -25,7 +25,7 @@ bool TransactionHistoryProxyModel::filterAcceptsRow(int sourceRow, const QModelI
     quint32 subaddrAccount;
     QSet<quint32> subaddrIndex;
 
-    m_history->transaction(sourceRow, [&description, &txid, &subaddrlabel, &subaddrAccount, &subaddrIndex](TransactionInfo &tInfo){
+    m_history->transaction(sourceRow, [&description, &txid, &subaddrlabel, &subaddrAccount, &subaddrIndex](TransactionRow &tInfo){
         description = tInfo.description();
         txid = tInfo.hash();
         subaddrlabel = tInfo.label();