Browse Source

bind transactionmodel

0.8
Wladimir J. van der Laan 14 years ago
parent
commit
213f763630
  1. 6
      gui/forms/addressbookdialog.ui
  2. 12
      gui/include/transactiontablemodel.h
  3. 8
      gui/src/addresstablemodel.cpp
  4. 1
      gui/src/bitcoingui.cpp
  5. 211
      gui/src/transactiontablemodel.cpp

6
gui/forms/addressbookdialog.ui

@ -32,6 +32,9 @@
<property name="selectionBehavior"> <property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum> <enum>QAbstractItemView::SelectRows</enum>
</property> </property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
<attribute name="verticalHeaderVisible"> <attribute name="verticalHeaderVisible">
<bool>false</bool> <bool>false</bool>
</attribute> </attribute>
@ -65,6 +68,9 @@
<property name="selectionBehavior"> <property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum> <enum>QAbstractItemView::SelectRows</enum>
</property> </property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
<attribute name="verticalHeaderVisible"> <attribute name="verticalHeaderVisible">
<bool>false</bool> <bool>false</bool>
</attribute> </attribute>

12
gui/include/transactiontablemodel.h

@ -4,11 +4,15 @@
#include <QAbstractTableModel> #include <QAbstractTableModel>
#include <QStringList> #include <QStringList>
class TransactionTableImpl;
class TransactionRecord;
class TransactionTableModel : public QAbstractTableModel class TransactionTableModel : public QAbstractTableModel
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit TransactionTableModel(QObject *parent = 0); explicit TransactionTableModel(QObject *parent = 0);
~TransactionTableModel();
enum { enum {
Status = 0, Status = 0,
@ -32,8 +36,16 @@ public:
QVariant data(const QModelIndex &index, int role) const; QVariant data(const QModelIndex &index, int role) const;
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;
private: private:
QStringList columns; QStringList columns;
TransactionTableImpl *impl;
QVariant formatTxStatus(const TransactionRecord *wtx) const;
QVariant formatTxDate(const TransactionRecord *wtx) const;
QVariant formatTxDescription(const TransactionRecord *wtx) const;
QVariant formatTxDebit(const TransactionRecord *wtx) const;
QVariant formatTxCredit(const TransactionRecord *wtx) const;
}; };
#endif #endif

8
gui/src/addresstablemodel.cpp

@ -12,7 +12,13 @@ AddressTableModel::AddressTableModel(QObject *parent) :
int AddressTableModel::rowCount(const QModelIndex &parent) const int AddressTableModel::rowCount(const QModelIndex &parent) const
{ {
return 5; Q_UNUSED(parent);
int retval = 0;
CRITICAL_BLOCK(cs_mapAddressBook)
{
retval = mapAddressBook.size();
}
return retval;
} }
int AddressTableModel::columnCount(const QModelIndex &parent) const int AddressTableModel::columnCount(const QModelIndex &parent) const

1
gui/src/bitcoingui.cpp

@ -200,6 +200,7 @@ QWidget *BitcoinGUI::createTabs()
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->verticalHeader()->hide(); transaction_table->verticalHeader()->hide();
transaction_table->horizontalHeader()->resizeSection( transaction_table->horizontalHeader()->resizeSection(

211
gui/src/transactiontablemodel.cpp

@ -2,11 +2,122 @@
#include "main.h" #include "main.h"
#include <QLocale> #include <QLocale>
#include <QDebug>
#include <QList>
const QString TransactionTableModel::Sent = "s"; const QString TransactionTableModel::Sent = "s";
const QString TransactionTableModel::Received = "r"; const QString TransactionTableModel::Received = "r";
const QString TransactionTableModel::Generated = "g"; const QString TransactionTableModel::Generated = "g";
/* Separate transaction record format from core.
* When the GUI is going to communicate with the core through the network,
* we'll need our own internal formats anyway.
*/
class TransactionRecord
{
public:
/* Information that never changes for the life of the transaction
*/
uint256 hash;
int64 time;
int64 credit;
int64 debit;
int64 change;
int64 lockTime;
int64 timeReceived;
bool isCoinBase;
int blockIndex;
/* Properties that change based on changes in block chain that come in
over the network.
*/
bool confirmed;
int depthInMainChain;
bool final;
int requestCount;
TransactionRecord(const CWalletTx &tx)
{
/* Copy immutable properties.
*/
hash = tx.GetHash();
time = tx.GetTxTime();
credit = tx.GetCredit(true);
debit = tx.GetDebit();
change = tx.GetChange();
isCoinBase = tx.IsCoinBase();
lockTime = tx.nLockTime;
timeReceived = tx.nTimeReceived;
/* Find the block the tx is in, store the index
*/
CBlockIndex* pindex = NULL;
std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(tx.hashBlock);
if (mi != mapBlockIndex.end())
pindex = (*mi).second;
blockIndex = (pindex ? pindex->nHeight : INT_MAX);
update(tx);
}
void update(const CWalletTx &tx)
{
confirmed = tx.IsConfirmed();
depthInMainChain = tx.GetDepthInMainChain();
final = tx.IsFinal();
requestCount = tx.GetRequestCount();
}
};
/* Internal implementation */
class TransactionTableImpl
{
public:
QList<TransactionRecord> cachedWallet;
/* Update our model of the wallet */
void updateWallet()
{
QList<int> insertedIndices;
QList<int> removedIndices;
cachedWallet.clear();
/* Query wallet from core, and compare with our own
representation.
*/
CRITICAL_BLOCK(cs_mapWallet)
{
for(std::map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
{
/* TODO: Make note of new and removed transactions */
/* insertedIndices */
/* removedIndices */
cachedWallet.append(TransactionRecord(it->second));
}
}
/* beginInsertRows(QModelIndex(), first, last) */
/* endInsertRows */
/* beginRemoveRows(QModelIndex(), first, last) */
/* beginEndRows */
}
int size()
{
return cachedWallet.size();
}
TransactionRecord *index(int idx)
{
if(idx >= 0 && idx < cachedWallet.size())
{
return &cachedWallet[idx];
} else {
return 0;
}
}
};
/* 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[] = { static int column_alignments[] = {
Qt::AlignLeft|Qt::AlignVCenter, Qt::AlignLeft|Qt::AlignVCenter,
@ -18,15 +129,32 @@ static int column_alignments[] = {
}; };
TransactionTableModel::TransactionTableModel(QObject *parent): TransactionTableModel::TransactionTableModel(QObject *parent):
QAbstractTableModel(parent) QAbstractTableModel(parent),
impl(new TransactionTableImpl())
{ {
columns << tr("Status") << tr("Date") << tr("Description") << tr("Debit") << tr("Credit"); columns << tr("Status") << tr("Date") << tr("Description") << tr("Debit") << tr("Credit");
impl->updateWallet();
}
TransactionTableModel::~TransactionTableModel()
{
delete impl;
} }
int TransactionTableModel::rowCount(const QModelIndex &parent) const int TransactionTableModel::rowCount(const QModelIndex &parent) const
{ {
Q_UNUSED(parent); Q_UNUSED(parent);
return 4; /*
int retval = 0;
CRITICAL_BLOCK(cs_mapWallet)
{
retval = mapWallet.size();
}
return retval;
*/
return impl->size();
} }
int TransactionTableModel::columnCount(const QModelIndex &parent) const int TransactionTableModel::columnCount(const QModelIndex &parent) const
@ -35,16 +163,72 @@ int TransactionTableModel::columnCount(const QModelIndex &parent) const
return columns.length(); return columns.length();
} }
QVariant TransactionTableModel::formatTxStatus(const TransactionRecord *wtx) const
{
return QVariant(QString("Test"));
#if 0
// Status
if (!wtx.IsFinal())
{
if (wtx.nLockTime < 500000000)
return strprintf(_("Open for %d blocks"), nBestHeight - wtx.nLockTime);
else
return strprintf(_("Open until %s"), DateTimeStr(wtx.nLockTime).c_str());
}
else
{
int nDepth = wtx.GetDepthInMainChain();
if (GetAdjustedTime() - wtx.nTimeReceived > 2 * 60 && wtx.GetRequestCount() == 0)
return strprintf(_("%d/offline?"), nDepth);
else if (nDepth < 6)
return strprintf(_("%d/unconfirmed"), nDepth);
else
return strprintf(_("%d confirmations"), nDepth);
}
#endif
}
QVariant TransactionTableModel::formatTxDate(const TransactionRecord *wtx) const
{
return QVariant();
}
QVariant TransactionTableModel::formatTxDescription(const TransactionRecord *wtx) const
{
return QVariant();
}
QVariant TransactionTableModel::formatTxDebit(const TransactionRecord *wtx) const
{
return QVariant();
}
QVariant TransactionTableModel::formatTxCredit(const TransactionRecord *wtx) const
{
return QVariant();
}
QVariant TransactionTableModel::data(const QModelIndex &index, int role) const QVariant TransactionTableModel::data(const QModelIndex &index, int role) const
{ {
if(!index.isValid()) if(!index.isValid())
return QVariant(); return QVariant();
TransactionRecord *rec = static_cast<TransactionRecord*>(index.internalPointer());
if(role == Qt::DisplayRole) if(role == Qt::DisplayRole)
{ {
/* index.row(), index.column() */ switch(index.column())
/* Return QString */ {
return QLocale::system().toString(index.row()); case Status:
return formatTxStatus(rec);
case Date:
return formatTxDate(rec);
case Description:
return formatTxDescription(rec);
case Debit:
return formatTxDebit(rec);
case Credit:
return formatTxCredit(rec);
}
} else if (role == Qt::TextAlignmentRole) } else if (role == Qt::TextAlignmentRole)
{ {
return column_alignments[index.column()]; return column_alignments[index.column()];
@ -82,8 +266,19 @@ QVariant TransactionTableModel::headerData(int section, Qt::Orientation orientat
Qt::ItemFlags TransactionTableModel::flags(const QModelIndex &index) const Qt::ItemFlags TransactionTableModel::flags(const QModelIndex &index) const
{ {
if (!index.isValid())
return Qt::ItemIsEnabled;
return QAbstractTableModel::flags(index); return QAbstractTableModel::flags(index);
} }
QModelIndex TransactionTableModel::index ( int row, int column, const QModelIndex & parent ) const
{
Q_UNUSED(parent);
TransactionRecord *data = impl->index(row);
if(data)
{
return createIndex(row, column, impl->index(row));
} else {
return QModelIndex();
}
}

Loading…
Cancel
Save