auto-update transaction list

This commit is contained in:
Wladimir J. van der Laan 2011-05-28 20:32:19 +02:00
parent f6c18bc9ed
commit 63760fa1cd
7 changed files with 98 additions and 21 deletions

View File

@ -56,7 +56,8 @@ HEADERS += gui/include/bitcoingui.h \
gui/src/clientmodel.h \
gui/include/clientmodel.h \
gui/include/guiutil.h \
gui/include/transactionrecord.h
gui/include/transactionrecord.h \
gui/include/guiconstants.h
SOURCES += gui/src/bitcoin.cpp gui/src/bitcoingui.cpp \
gui/src/transactiontablemodel.cpp \
gui/src/addresstablemodel.cpp \

View File

@ -0,0 +1,11 @@
#ifndef GUICONSTANTS_H
#define GUICONSTANTS_H
/* milliseconds between model updates */
static const int MODEL_UPDATE_DELAY = 250;
/* size of cache */
static const unsigned int WALLET_CACHE_SIZE = 100;
#endif // GUICONSTANTS_H

View File

@ -75,6 +75,8 @@ public:
{
}
/* Decompose CWallet transaction to model transaction records.
*/
static bool showTransaction(const CWalletTx &wtx);
static QList<TransactionRecord> decomposeTransaction(const CWalletTx &wtx);

View File

@ -37,8 +37,6 @@ public:
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
Qt::ItemFlags flags(const QModelIndex &index) const;
QModelIndex index ( int row, int column, const QModelIndex & parent = QModelIndex() ) const;
public slots:
void updateWallet();
private:
QStringList columns;
TransactionTableImpl *impl;
@ -48,6 +46,9 @@ private:
QVariant formatTxDescription(const TransactionRecord *wtx) const;
QVariant formatTxDebit(const TransactionRecord *wtx) const;
QVariant formatTxCredit(const TransactionRecord *wtx) const;
private slots:
void update();
};
#endif

View File

@ -147,7 +147,7 @@ void BitcoinGUI::setModel(ClientModel *model)
this->model = model;
setBalance(model->getBalance());
connect(model, SIGNAL(balanceChanged(double)), this, SLOT(setBalance(double)));
connect(model, SIGNAL(balanceChanged(qint64)), this, SLOT(setBalance(qint64)));
setNumConnections(model->getNumConnections());
connect(model, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int)));
@ -197,12 +197,14 @@ QWidget *BitcoinGUI::createTabs()
proxy_model->setDynamicSortFilter(true);
proxy_model->setFilterRole(TransactionTableModel::TypeRole);
proxy_model->setFilterRegExp(QRegExp(tab_filters.at(i)));
proxy_model->setSortRole(Qt::EditRole);
QTableView *transaction_table = new QTableView(this);
transaction_table->setModel(proxy_model);
transaction_table->setSelectionBehavior(QAbstractItemView::SelectRows);
transaction_table->setSelectionMode(QAbstractItemView::ExtendedSelection);
transaction_table->setSortingEnabled(true);
transaction_table->sortByColumn(TransactionTableModel::Status, Qt::DescendingOrder);
transaction_table->verticalHeader()->hide();
transaction_table->horizontalHeader()->resizeSection(

View File

@ -1,11 +1,9 @@
#include "clientmodel.h"
#include "main.h"
#include "guiconstants.h"
#include <QTimer>
/* milliseconds between model updates */
const int MODEL_UPDATE_DELAY = 250;
ClientModel::ClientModel(QObject *parent) :
QObject(parent)
{

View File

@ -1,12 +1,14 @@
#include "transactiontablemodel.h"
#include "guiutil.h"
#include "transactionrecord.h"
#include "guiconstants.h"
#include "main.h"
#include <QLocale>
#include <QDebug>
#include <QList>
#include <QColor>
#include <QTimer>
const QString TransactionTableModel::Sent = "s";
const QString TransactionTableModel::Received = "r";
@ -16,14 +18,15 @@ const QString TransactionTableModel::Other = "o";
class TransactionTableImpl
{
public:
/* Local cache of wallet.
* As it is in the same order as the CWallet, by definition
* this is sorted by sha256.
*/
QList<TransactionRecord> cachedWallet;
/* Update our model of the wallet */
void updateWallet()
void refreshWallet()
{
QList<int> insertedIndices;
QList<int> removedIndices;
qDebug() << "refreshWallet";
cachedWallet.clear();
/* Query wallet from core, and compare with our own
@ -45,6 +48,26 @@ public:
/* beginEndRows */
}
/* Update our model of the wallet.
Call with list of hashes of transactions that were added, removed or changed.
*/
void updateWallet(const QList<uint256> &updated)
{
/* TODO: update only transactions in updated, and only if
the transactions are really part of the visible wallet.
Update status of the other transactions in the cache just in case,
because this call means that a new block came in.
*/
qDebug() << "updateWallet";
foreach(uint256 hash, updated)
{
qDebug() << " " << QString::fromStdString(hash.ToString());
}
refreshWallet();
}
int size()
{
return cachedWallet.size();
@ -59,6 +82,7 @@ public:
return 0;
}
}
};
/* Credit and Debit columns are right-aligned as they contain numbers */
@ -77,7 +101,11 @@ TransactionTableModel::TransactionTableModel(QObject *parent):
{
columns << tr("Status") << tr("Date") << tr("Description") << tr("Debit") << tr("Credit");
impl->updateWallet();
impl->refreshWallet();
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(update()));
timer->start(MODEL_UPDATE_DELAY);
}
TransactionTableModel::~TransactionTableModel()
@ -85,15 +113,33 @@ TransactionTableModel::~TransactionTableModel()
delete impl;
}
void TransactionTableModel::updateWallet()
void TransactionTableModel::update()
{
/* TODO: improve this, way too brute-force at the moment,
only update transactions that actually changed, and add/remove
transactions that were added/removed.
*/
beginResetModel();
impl->updateWallet();
endResetModel();
QList<uint256> updated;
/* Check if there are changes to wallet map */
TRY_CRITICAL_BLOCK(cs_mapWallet)
{
if(!vWalletUpdated.empty())
{
BOOST_FOREACH(uint256 hash, vWalletUpdated)
{
updated.append(hash);
}
vWalletUpdated.clear();
}
}
if(!updated.empty())
{
/* TODO: improve this, way too brute-force at the moment,
only update transactions that actually changed, and add/remove
transactions that were added/removed.
*/
beginResetModel();
impl->updateWallet(updated);
endResetModel();
}
}
int TransactionTableModel::rowCount(const QModelIndex &parent) const
@ -261,6 +307,22 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const
case Credit:
return formatTxCredit(rec);
}
} else if(role == Qt::EditRole)
{
/* Edit role is used for sorting so return the real values */
switch(index.column())
{
case Status:
return QString::fromStdString(rec->status.sortKey);
case Date:
return rec->time;
case Description:
return formatTxDescription(rec);
case Debit:
return rec->debit;
case Credit:
return rec->credit;
}
} else if (role == Qt::TextAlignmentRole)
{
return column_alignments[index.column()];