update core to d0d80170a2ca73004e08fb85007fe055cbf4e411 (CWallet class)
[novacoin.git] / src / qt / transactiontablemodel.cpp
index eeb948b..18ab421 100644 (file)
@@ -2,9 +2,10 @@
 #include "guiutil.h"
 #include "transactionrecord.h"
 #include "guiconstants.h"
-#include "main.h"
 #include "transactiondesc.h"
 
+#include "headers.h"
+
 #include <QLocale>
 #include <QDebug>
 #include <QList>
@@ -17,7 +18,7 @@ const QString TransactionTableModel::Sent = "s";
 const QString TransactionTableModel::Received = "r";
 const QString TransactionTableModel::Other = "o";
 
-/* Comparison operator for sort/binary search of model tx list */
+// Comparison operator for sort/binary search of model tx list
 struct TxLessThan
 {
     bool operator()(const TransactionRecord &a, const TransactionRecord &b) const
@@ -34,14 +35,15 @@ struct TxLessThan
     }
 };
 
-/* Private implementation */
+// Private implementation
 struct TransactionTablePriv
 {
-    TransactionTablePriv(TransactionTableModel *parent):
+    TransactionTablePriv(CWallet *wallet, TransactionTableModel *parent):
+            wallet(wallet),
             parent(parent)
     {
     }
-
+    CWallet *wallet;
     TransactionTableModel *parent;
 
     /* Local cache of wallet.
@@ -50,48 +52,48 @@ struct TransactionTablePriv
      */
     QList<TransactionRecord> cachedWallet;
 
+    /* Query entire wallet anew from core.
+     */
     void refreshWallet()
     {
 #ifdef WALLET_UPDATE_DEBUG
         qDebug() << "refreshWallet";
 #endif
-        /* Query entire wallet from core.
-         */
         cachedWallet.clear();
-        CRITICAL_BLOCK(cs_mapWallet)
+        CRITICAL_BLOCK(wallet->cs_mapWallet)
         {
-            for(std::map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
+            for(std::map<uint256, CWalletTx>::iterator it = wallet->mapWallet.begin(); it != wallet->mapWallet.end(); ++it)
             {
-                cachedWallet.append(TransactionRecord::decomposeTransaction(it->second));
+                cachedWallet.append(TransactionRecord::decomposeTransaction(wallet, it->second));
             }
         }
     }
 
-    /* Update our model of the wallet incrementally.
+    /* Update our model of the wallet incrementally, to synchronize our model of the wallet
+       with that of the core.
+
        Call with list of hashes of transactions that were added, removed or changed.
      */
     void updateWallet(const QList<uint256> &updated)
     {
-        /* Walk through updated transactions, update model as needed.
-         */
+        // Walk through updated transactions, update model as needed.
 #ifdef WALLET_UPDATE_DEBUG
         qDebug() << "updateWallet";
 #endif
-        /* Sort update list, and iterate through it in reverse, so that model updates
-           can be emitted from end to beginning (so that earlier updates will not influence
-           the indices of latter ones).
-         */
+        // Sort update list, and iterate through it in reverse, so that model updates
+        //  can be emitted from end to beginning (so that earlier updates will not influence
+        // the indices of latter ones).
         QList<uint256> updated_sorted = updated;
         qSort(updated_sorted);
 
-        CRITICAL_BLOCK(cs_mapWallet)
+        CRITICAL_BLOCK(wallet->cs_mapWallet)
         {
             for(int update_idx = updated_sorted.size()-1; update_idx >= 0; --update_idx)
             {
                 const uint256 &hash = updated_sorted.at(update_idx);
                 /* Find transaction in wallet */
-                std::map<uint256, CWalletTx>::iterator mi = mapWallet.find(hash);
-                bool inWallet = mi != mapWallet.end();
+                std::map<uint256, CWalletTx>::iterator mi = wallet->mapWallet.find(hash);
+                bool inWallet = mi != wallet->mapWallet.end();
                 /* Find bounds of this transaction in model */
                 QList<TransactionRecord>::iterator lower = qLowerBound(
                     cachedWallet.begin(), cachedWallet.end(), hash, TxLessThan());
@@ -100,6 +102,7 @@ struct TransactionTablePriv
                 int lowerIndex = (lower - cachedWallet.begin());
                 int upperIndex = (upper - cachedWallet.begin());
 
+                // Determine if transaction is in model already
                 bool inModel = false;
                 if(lower != upper)
                 {
@@ -113,9 +116,9 @@ struct TransactionTablePriv
 
                 if(inWallet && !inModel)
                 {
-                    /* Added -- insert at the right position */
+                    // Added -- insert at the right position
                     QList<TransactionRecord> toInsert =
-                            TransactionRecord::decomposeTransaction(mi->second);
+                            TransactionRecord::decomposeTransaction(wallet, mi->second);
                     if(!toInsert.isEmpty()) /* only if something to insert */
                     {
                         parent->beginInsertRows(QModelIndex(), lowerIndex, lowerIndex+toInsert.size()-1);
@@ -130,14 +133,14 @@ struct TransactionTablePriv
                 }
                 else if(!inWallet && inModel)
                 {
-                    /* Removed -- remove entire transaction from table */
+                    // Removed -- remove entire transaction from table
                     parent->beginRemoveRows(QModelIndex(), lowerIndex, upperIndex-1);
                     cachedWallet.erase(lower, upper);
                     parent->endRemoveRows();
                 }
                 else if(inWallet && inModel)
                 {
-                    /* Updated -- nothing to do, status update will take care of this */
+                    // Updated -- nothing to do, status update will take care of this
                 }
             }
         }
@@ -154,17 +157,16 @@ struct TransactionTablePriv
         {
             TransactionRecord *rec = &cachedWallet[idx];
 
-            /* If a status update is needed (blocks came in since last check),
-               update the status of this transaction from the wallet. Otherwise,
-               simply re-use the cached status.
-             */
+            // If a status update is needed (blocks came in since last check),
+            //  update the status of this transaction from the wallet. Otherwise,
+            // simply re-use the cached status.
             if(rec->statusUpdateNeeded())
             {
-                CRITICAL_BLOCK(cs_mapWallet)
+                CRITICAL_BLOCK(wallet->cs_mapWallet)
                 {
-                    std::map<uint256, CWalletTx>::iterator mi = mapWallet.find(rec->hash);
+                    std::map<uint256, CWalletTx>::iterator mi = wallet->mapWallet.find(rec->hash);
 
-                    if(mi != mapWallet.end())
+                    if(mi != wallet->mapWallet.end())
                     {
                         rec->updateStatus(mi->second);
                     }
@@ -180,12 +182,12 @@ struct TransactionTablePriv
 
     QString describe(TransactionRecord *rec)
     {
-        CRITICAL_BLOCK(cs_mapWallet)
+        CRITICAL_BLOCK(wallet->cs_mapWallet)
         {
-            std::map<uint256, CWalletTx>::iterator mi = mapWallet.find(rec->hash);
-            if(mi != mapWallet.end())
+            std::map<uint256, CWalletTx>::iterator mi = wallet->mapWallet.find(rec->hash);
+            if(mi != wallet->mapWallet.end())
             {
-                return QString::fromStdString(TransactionDesc::toHTML(mi->second));
+                return QString::fromStdString(TransactionDesc::toHTML(wallet, mi->second));
             }
         }
         return QString("");
@@ -193,7 +195,7 @@ struct TransactionTablePriv
 
 };
 
-/* Credit and Debit columns are right-aligned as they contain numbers */
+// Credit and Debit columns are right-aligned as they contain numbers
 static int column_alignments[] = {
         Qt::AlignLeft|Qt::AlignVCenter,
         Qt::AlignLeft|Qt::AlignVCenter,
@@ -203,9 +205,10 @@ static int column_alignments[] = {
         Qt::AlignLeft|Qt::AlignVCenter
     };
 
-TransactionTableModel::TransactionTableModel(QObject *parent):
+TransactionTableModel::TransactionTableModel(CWallet* wallet, QObject *parent):
         QAbstractTableModel(parent),
-        priv(new TransactionTablePriv(this))
+        wallet(wallet),
+        priv(new TransactionTablePriv(wallet, this))
 {
     columns << tr("Status") << tr("Date") << tr("Description") << tr("Debit") << tr("Credit");
 
@@ -225,16 +228,16 @@ void TransactionTableModel::update()
 {
     QList<uint256> updated;
 
-    /* Check if there are changes to wallet map */
-    TRY_CRITICAL_BLOCK(cs_mapWallet)
+    // Check if there are changes to wallet map
+    TRY_CRITICAL_BLOCK(wallet->cs_mapWallet)
     {
-        if(!vWalletUpdated.empty())
+        if(!wallet->vWalletUpdated.empty())
         {
-            BOOST_FOREACH(uint256 hash, vWalletUpdated)
+            BOOST_FOREACH(uint256 hash, wallet->vWalletUpdated)
             {
                 updated.append(hash);
             }
-            vWalletUpdated.clear();
+            wallet->vWalletUpdated.clear();
         }
     }
 
@@ -242,9 +245,8 @@ void TransactionTableModel::update()
     {
         priv->updateWallet(updated);
 
-        /* Status (number of confirmations) and (possibly) description
-           columns changed for all rows.
-         */
+        // Status (number of confirmations) and (possibly) description
+        //  columns changed for all rows.
         emit dataChanged(index(0, Status), index(priv->size()-1, Status));
         emit dataChanged(index(0, Description), index(priv->size()-1, Description));
     }
@@ -272,13 +274,13 @@ QVariant TransactionTableModel::formatTxStatus(const TransactionRecord *wtx) con
         status = tr("Open for %n block(s)","",wtx->status.open_for);
         break;
     case TransactionStatus::OpenUntilDate:
-        status = tr("Open until ") + GUIUtil::DateTimeStr(wtx->status.open_for);
+        status = tr("Open until %1").arg(GUIUtil::DateTimeStr(wtx->status.open_for));
         break;
     case TransactionStatus::Offline:
         status = tr("Offline (%1)").arg(wtx->status.depth);
         break;
     case TransactionStatus::Unconfirmed:
-        status = tr("Unconfirmed (%1)").arg(wtx->status.depth);
+        status = tr("Unconfirmed (%1/%2)").arg(wtx->status.depth).arg(TransactionRecord::NumConfirmations);
         break;
     case TransactionStatus::HaveConfirmations:
         status = tr("Confirmed (%1)").arg(wtx->status.depth);
@@ -304,13 +306,13 @@ QVariant TransactionTableModel::formatTxDate(const TransactionRecord *wtx) const
      address[0:12]... (label)
    otherwise just return address
  */
-std::string lookupAddress(const std::string &address)
+std::string TransactionTableModel::lookupAddress(const std::string &address) const
 {
     std::string description;
-    CRITICAL_BLOCK(cs_mapAddressBook)
+    CRITICAL_BLOCK(wallet->cs_mapAddressBook)
     {
-        std::map<std::string, std::string>::iterator mi = mapAddressBook.find(address);
-        if (mi != mapAddressBook.end() && !(*mi).second.empty())
+        std::map<std::string, std::string>::iterator mi = wallet->mapAddressBook.find(address);
+        if (mi != wallet->mapAddressBook.end() && !(*mi).second.empty())
         {
             std::string label = (*mi).second;
             description += address.substr(0,12) + "... ";
@@ -442,11 +444,9 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const
     }
     else if(role == Qt::DisplayRole)
     {
-        /* Delegate to specific column handlers */
+        // Delegate to specific column handlers
         switch(index.column())
         {
-        //case Status:
-        //    return formatTxStatus(rec);
         case Date:
             return formatTxDate(rec);
         case Description:
@@ -459,7 +459,7 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const
     }
     else if(role == Qt::EditRole)
     {
-        /* Edit role is used for sorting so return the real values */
+        // Edit role is used for sorting so return the real values
         switch(index.column())
         {
         case Status:
@@ -488,11 +488,7 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const
     else if (role == Qt::ForegroundRole)
     {
         /* Non-confirmed transactions are grey */
-        if(rec->status.confirmed)
-        {
-            return QColor(0, 0, 0);
-        }
-        else
+        if(!rec->status.confirmed)
         {
             return QColor(128, 128, 128);
         }
@@ -536,7 +532,7 @@ QVariant TransactionTableModel::headerData(int section, Qt::Orientation orientat
             switch(section)
             {
             case Status:
-                return tr("Transaction status. Hover over this field to show number of transactions.");
+                return tr("Transaction status. Hover over this field to show number of confirmations.");
             case Date:
                 return tr("Date and time that the transaction was received.");
             case Description: