Browse Source

auto-update transaction list

0.8
Wladimir J. van der Laan 14 years ago
parent
commit
63760fa1cd
  1. 3
      bitcoin.pro
  2. 11
      gui/include/guiconstants.h
  3. 2
      gui/include/transactionrecord.h
  4. 5
      gui/include/transactiontablemodel.h
  5. 4
      gui/src/bitcoingui.cpp
  6. 4
      gui/src/clientmodel.cpp
  7. 78
      gui/src/transactiontablemodel.cpp

3
bitcoin.pro

@ -56,7 +56,8 @@ HEADERS += gui/include/bitcoingui.h \
gui/src/clientmodel.h \ gui/src/clientmodel.h \
gui/include/clientmodel.h \ gui/include/clientmodel.h \
gui/include/guiutil.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 \ SOURCES += gui/src/bitcoin.cpp gui/src/bitcoingui.cpp \
gui/src/transactiontablemodel.cpp \ gui/src/transactiontablemodel.cpp \
gui/src/addresstablemodel.cpp \ gui/src/addresstablemodel.cpp \

11
gui/include/guiconstants.h

@ -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

2
gui/include/transactionrecord.h

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

5
gui/include/transactiontablemodel.h

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

4
gui/src/bitcoingui.cpp

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

4
gui/src/clientmodel.cpp

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

78
gui/src/transactiontablemodel.cpp

@ -1,12 +1,14 @@
#include "transactiontablemodel.h" #include "transactiontablemodel.h"
#include "guiutil.h" #include "guiutil.h"
#include "transactionrecord.h" #include "transactionrecord.h"
#include "guiconstants.h"
#include "main.h" #include "main.h"
#include <QLocale> #include <QLocale>
#include <QDebug> #include <QDebug>
#include <QList> #include <QList>
#include <QColor> #include <QColor>
#include <QTimer>
const QString TransactionTableModel::Sent = "s"; const QString TransactionTableModel::Sent = "s";
const QString TransactionTableModel::Received = "r"; const QString TransactionTableModel::Received = "r";
@ -16,14 +18,15 @@ const QString TransactionTableModel::Other = "o";
class TransactionTableImpl class TransactionTableImpl
{ {
public: 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; QList<TransactionRecord> cachedWallet;
/* Update our model of the wallet */ void refreshWallet()
void updateWallet()
{ {
QList<int> insertedIndices; qDebug() << "refreshWallet";
QList<int> removedIndices;
cachedWallet.clear(); cachedWallet.clear();
/* Query wallet from core, and compare with our own /* Query wallet from core, and compare with our own
@ -45,6 +48,26 @@ public:
/* beginEndRows */ /* 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() int size()
{ {
return cachedWallet.size(); return cachedWallet.size();
@ -59,6 +82,7 @@ public:
return 0; return 0;
} }
} }
}; };
/* Credit and Debit columns are right-aligned as they contain numbers */ /* 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"); 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() TransactionTableModel::~TransactionTableModel()
@ -85,15 +113,33 @@ TransactionTableModel::~TransactionTableModel()
delete impl; delete impl;
} }
void TransactionTableModel::updateWallet() void TransactionTableModel::update()
{ {
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, /* TODO: improve this, way too brute-force at the moment,
only update transactions that actually changed, and add/remove only update transactions that actually changed, and add/remove
transactions that were added/removed. transactions that were added/removed.
*/ */
beginResetModel(); beginResetModel();
impl->updateWallet(); impl->updateWallet(updated);
endResetModel(); endResetModel();
}
} }
int TransactionTableModel::rowCount(const QModelIndex &parent) const int TransactionTableModel::rowCount(const QModelIndex &parent) const
@ -261,6 +307,22 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const
case Credit: case Credit:
return formatTxCredit(rec); 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) } else if (role == Qt::TextAlignmentRole)
{ {
return column_alignments[index.column()]; return column_alignments[index.column()];

Loading…
Cancel
Save