Change transaction table:

- Split "Description" column into "Type" and "Address", to make sorting easier (and facilitate filtering in the future)
- Merged "credit" and "debit" columns into one "amount" column that can be black (positive) or red (negative)
This commit is contained in:
Wladimir J. van der Laan 2011-06-26 22:47:02 +02:00
parent e8ef3da713
commit 34fa178243
4 changed files with 102 additions and 87 deletions

View File

@ -265,6 +265,7 @@ void BitcoinGUI::setTabsModel(QAbstractItemModel *transaction_model)
QTableView *transaction_table = transactionViews.at(i); QTableView *transaction_table = transactionViews.at(i);
transaction_table->setModel(proxy_model); transaction_table->setModel(proxy_model);
transaction_table->setAlternatingRowColors(true);
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);
@ -275,12 +276,12 @@ void BitcoinGUI::setTabsModel(QAbstractItemModel *transaction_model)
TransactionTableModel::Status, 23); TransactionTableModel::Status, 23);
transaction_table->horizontalHeader()->resizeSection( transaction_table->horizontalHeader()->resizeSection(
TransactionTableModel::Date, 120); TransactionTableModel::Date, 120);
transaction_table->horizontalHeader()->resizeSection(
TransactionTableModel::Type, 120);
transaction_table->horizontalHeader()->setResizeMode( transaction_table->horizontalHeader()->setResizeMode(
TransactionTableModel::Description, QHeaderView::Stretch); TransactionTableModel::ToAddress, QHeaderView::Stretch);
transaction_table->horizontalHeader()->resizeSection( transaction_table->horizontalHeader()->resizeSection(
TransactionTableModel::Debit, 79); TransactionTableModel::Amount, 79);
transaction_table->horizontalHeader()->resizeSection(
TransactionTableModel::Credit, 79);
} }
connect(transaction_model, SIGNAL(rowsInserted(const QModelIndex &, int, int)), connect(transaction_model, SIGNAL(rowsInserted(const QModelIndex &, int, int)),
@ -457,23 +458,24 @@ void BitcoinGUI::transactionDetails(const QModelIndex& idx)
void BitcoinGUI::incomingTransaction(const QModelIndex & parent, int start, int end) void BitcoinGUI::incomingTransaction(const QModelIndex & parent, int start, int end)
{ {
TransactionTableModel *ttm = model->getTransactionTableModel(); TransactionTableModel *ttm = model->getTransactionTableModel();
qint64 credit = ttm->index(start, TransactionTableModel::Credit, parent) qint64 amount = ttm->index(start, TransactionTableModel::Amount, parent)
.data(Qt::EditRole).toULongLong(); .data(Qt::EditRole).toULongLong();
qint64 debit = ttm->index(start, TransactionTableModel::Debit, parent) if(amount>0 && !model->inInitialBlockDownload())
.data(Qt::EditRole).toULongLong();
if((credit+debit)>0 && !model->inInitialBlockDownload())
{ {
// On incoming transaction, make an info balloon // On incoming transaction, make an info balloon
// Unless the initial block download is in progress, to prevent balloon-spam // Unless the initial block download is in progress, to prevent balloon-spam
QString date = ttm->index(start, TransactionTableModel::Date, parent) QString date = ttm->index(start, TransactionTableModel::Date, parent)
.data().toString(); .data().toString();
QString description = ttm->index(start, TransactionTableModel::Description, parent) QString type = ttm->index(start, TransactionTableModel::Type, parent)
.data().toString();
QString address = ttm->index(start, TransactionTableModel::ToAddress, parent)
.data().toString(); .data().toString();
trayIcon->showMessage(tr("Incoming transaction"), trayIcon->showMessage(tr("Incoming transaction"),
"Date: " + date + "\n" + tr("Date: ") + date + "\n" +
"Amount: " + QString::fromStdString(FormatMoney(credit+debit, true)) + "\n" + tr("Amount: ") + QString::fromStdString(FormatMoney(amount, true)) + "\n" +
description, tr("Type: ") + type + "\n" +
tr("Address: ") + address + "\n",
QSystemTrayIcon::Information); QSystemTrayIcon::Information);
} }
} }

View File

@ -17,7 +17,7 @@
<item> <item>
<widget class="QTabWidget" name="tabWidget"> <widget class="QTabWidget" name="tabWidget">
<property name="currentIndex"> <property name="currentIndex">
<number>1</number> <number>0</number>
</property> </property>
<widget class="QWidget" name="sendTab"> <widget class="QWidget" name="sendTab">
<property name="toolTip"> <property name="toolTip">
@ -29,6 +29,9 @@
<layout class="QVBoxLayout" name="verticalLayout_2"> <layout class="QVBoxLayout" name="verticalLayout_2">
<item> <item>
<widget class="QTableView" name="sendTableView"> <widget class="QTableView" name="sendTableView">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionMode"> <property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum> <enum>QAbstractItemView::SingleSelection</enum>
</property> </property>
@ -68,6 +71,9 @@
</item> </item>
<item> <item>
<widget class="QTableView" name="receiveTableView"> <widget class="QTableView" name="receiveTableView">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionMode"> <property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum> <enum>QAbstractItemView::SingleSelection</enum>
</property> </property>

View File

@ -18,6 +18,15 @@ const QString TransactionTableModel::Sent = "s";
const QString TransactionTableModel::Received = "r"; const QString TransactionTableModel::Received = "r";
const QString TransactionTableModel::Other = "o"; const QString TransactionTableModel::Other = "o";
// Credit and Debit columns are right-aligned as they contain numbers
static int column_alignments[] = {
Qt::AlignLeft|Qt::AlignVCenter,
Qt::AlignLeft|Qt::AlignVCenter,
Qt::AlignLeft|Qt::AlignVCenter,
Qt::AlignLeft|Qt::AlignVCenter,
Qt::AlignRight|Qt::AlignVCenter
};
// Comparison operator for sort/binary search of model tx list // Comparison operator for sort/binary search of model tx list
struct TxLessThan struct TxLessThan
{ {
@ -195,22 +204,12 @@ struct TransactionTablePriv
}; };
// Credit and Debit columns are right-aligned as they contain numbers
static int column_alignments[] = {
Qt::AlignLeft|Qt::AlignVCenter,
Qt::AlignLeft|Qt::AlignVCenter,
Qt::AlignLeft|Qt::AlignVCenter,
Qt::AlignRight|Qt::AlignVCenter,
Qt::AlignRight|Qt::AlignVCenter,
Qt::AlignLeft|Qt::AlignVCenter
};
TransactionTableModel::TransactionTableModel(CWallet* wallet, QObject *parent): TransactionTableModel::TransactionTableModel(CWallet* wallet, QObject *parent):
QAbstractTableModel(parent), QAbstractTableModel(parent),
wallet(wallet), wallet(wallet),
priv(new TransactionTablePriv(wallet, this)) priv(new TransactionTablePriv(wallet, this))
{ {
columns << tr("Status") << tr("Date") << tr("Description") << tr("Debit") << tr("Credit"); columns << tr("Status") << tr("Date") << tr("Type") << tr("Address") << tr("Amount");
priv->refreshWallet(); priv->refreshWallet();
@ -248,7 +247,7 @@ void TransactionTableModel::update()
// Status (number of confirmations) and (possibly) description // Status (number of confirmations) and (possibly) description
// columns changed for all rows. // columns changed for all rows.
emit dataChanged(index(0, Status), index(priv->size()-1, Status)); emit dataChanged(index(0, Status), index(priv->size()-1, Status));
emit dataChanged(index(0, Description), index(priv->size()-1, Description)); emit dataChanged(index(0, ToAddress), index(priv->size()-1, ToAddress));
} }
} }
@ -326,42 +325,70 @@ std::string TransactionTableModel::lookupAddress(const std::string &address) con
return description; return description;
} }
QVariant TransactionTableModel::formatTxDescription(const TransactionRecord *wtx) const QVariant TransactionTableModel::formatTxType(const TransactionRecord *wtx) const
{ {
QString description; QString description;
switch(wtx->type) switch(wtx->type)
{ {
case TransactionRecord::RecvWithAddress: case TransactionRecord::RecvWithAddress:
description = tr("Received with: ") + QString::fromStdString(lookupAddress(wtx->address)); description = tr("Received with");
break; break;
case TransactionRecord::RecvFromIP: case TransactionRecord::RecvFromIP:
description = tr("Received from IP: ") + QString::fromStdString(wtx->address); description = tr("Received from IP");
break; break;
case TransactionRecord::SendToAddress: case TransactionRecord::SendToAddress:
description = tr("Sent to: ") + QString::fromStdString(lookupAddress(wtx->address)); description = tr("Sent to");
break; break;
case TransactionRecord::SendToIP: case TransactionRecord::SendToIP:
description = tr("Sent to IP: ") + QString::fromStdString(wtx->address); description = tr("Sent to IP");
break; break;
case TransactionRecord::SendToSelf: case TransactionRecord::SendToSelf:
description = tr("Payment to yourself"); description = tr("Payment to yourself");
break; break;
case TransactionRecord::Generated:
description = tr("Generated");
break;
}
return QVariant(description);
}
QVariant TransactionTableModel::formatTxToAddress(const TransactionRecord *wtx) const
{
QString description;
switch(wtx->type)
{
case TransactionRecord::RecvWithAddress:
description = QString::fromStdString(lookupAddress(wtx->address));
break;
case TransactionRecord::RecvFromIP:
description = QString::fromStdString(wtx->address);
break;
case TransactionRecord::SendToAddress:
description = QString::fromStdString(lookupAddress(wtx->address));
break;
case TransactionRecord::SendToIP:
description = QString::fromStdString(wtx->address);
break;
case TransactionRecord::SendToSelf:
description = QString();
break;
case TransactionRecord::Generated: case TransactionRecord::Generated:
switch(wtx->status.maturity) switch(wtx->status.maturity)
{ {
case TransactionStatus::Immature: case TransactionStatus::Immature:
description = tr("Generated (matures in %n more blocks)", "", description = tr("(matures in %n more blocks)", "",
wtx->status.matures_in); wtx->status.matures_in);
break; break;
case TransactionStatus::Mature: case TransactionStatus::Mature:
description = tr("Generated"); description = QString();
break; break;
case TransactionStatus::MaturesWarning: case TransactionStatus::MaturesWarning:
description = tr("Generated - Warning: This block was not received by any other nodes and will probably not be accepted!"); description = tr("(Warning: This block was not received by any other nodes and will probably not be accepted!)");
break; break;
case TransactionStatus::NotAccepted: case TransactionStatus::NotAccepted:
description = tr("Generated (not accepted)"); description = tr("(not accepted)");
break; break;
} }
break; break;
@ -369,38 +396,14 @@ QVariant TransactionTableModel::formatTxDescription(const TransactionRecord *wtx
return QVariant(description); return QVariant(description);
} }
QVariant TransactionTableModel::formatTxDebit(const TransactionRecord *wtx) const QVariant TransactionTableModel::formatTxAmount(const TransactionRecord *wtx) const
{ {
if(wtx->debit) QString str = QString::fromStdString(FormatMoney(wtx->credit + wtx->debit));
if(!wtx->status.confirmed || wtx->status.maturity != TransactionStatus::Mature)
{ {
QString str = QString::fromStdString(FormatMoney(wtx->debit)); str = QString("[") + str + QString("]");
if(!wtx->status.confirmed || wtx->status.maturity != TransactionStatus::Mature)
{
str = QString("[") + str + QString("]");
}
return QVariant(str);
}
else
{
return QVariant();
}
}
QVariant TransactionTableModel::formatTxCredit(const TransactionRecord *wtx) const
{
if(wtx->credit)
{
QString str = QString::fromStdString(FormatMoney(wtx->credit));
if(!wtx->status.confirmed || wtx->status.maturity != TransactionStatus::Mature)
{
str = QString("[") + str + QString("]");
}
return QVariant(str);
}
else
{
return QVariant();
} }
return QVariant(str);
} }
QVariant TransactionTableModel::formatTxDecoration(const TransactionRecord *wtx) const QVariant TransactionTableModel::formatTxDecoration(const TransactionRecord *wtx) const
@ -449,12 +452,12 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const
{ {
case Date: case Date:
return formatTxDate(rec); return formatTxDate(rec);
case Description: case Type:
return formatTxDescription(rec); return formatTxType(rec);
case Debit: case ToAddress:
return formatTxDebit(rec); return formatTxToAddress(rec);
case Credit: case Amount:
return formatTxCredit(rec); return formatTxAmount(rec);
} }
} }
else if(role == Qt::EditRole) else if(role == Qt::EditRole)
@ -466,12 +469,12 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const
return QString::fromStdString(rec->status.sortKey); return QString::fromStdString(rec->status.sortKey);
case Date: case Date:
return rec->time; return rec->time;
case Description: case Type:
return formatTxDescription(rec); return formatTxType(rec);
case Debit: case ToAddress:
return rec->debit; return formatTxToAddress(rec);
case Credit: case Amount:
return rec->credit; return rec->credit + rec->debit;
} }
} }
else if (role == Qt::ToolTipRole) else if (role == Qt::ToolTipRole)
@ -492,6 +495,10 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const
{ {
return QColor(128, 128, 128); return QColor(128, 128, 128);
} }
if(index.column() == Amount && (rec->credit+rec->debit) < 0)
{
return QColor(255, 0, 0);
}
} }
else if (role == TypeRole) else if (role == TypeRole)
{ {
@ -535,12 +542,12 @@ QVariant TransactionTableModel::headerData(int section, Qt::Orientation orientat
return tr("Transaction status. Hover over this field to show number of confirmations."); return tr("Transaction status. Hover over this field to show number of confirmations.");
case Date: case Date:
return tr("Date and time that the transaction was received."); return tr("Date and time that the transaction was received.");
case Description: case Type:
return tr("Short description of the transaction."); return tr("Type of transaction.");
case Debit: case ToAddress:
return tr("Amount removed from balance."); return tr("Destination address of transaction.");
case Credit: case Amount:
return tr("Amount added to balance."); return tr("Amount removed from or added to balance.");
} }
} }
} }

View File

@ -18,9 +18,9 @@ public:
enum { enum {
Status = 0, Status = 0,
Date = 1, Date = 1,
Description = 2, Type = 2,
Debit = 3, ToAddress = 3,
Credit = 4 Amount = 4
} ColumnIndex; } ColumnIndex;
enum { enum {
@ -47,9 +47,9 @@ private:
std::string lookupAddress(const std::string &address) const; std::string lookupAddress(const std::string &address) const;
QVariant formatTxStatus(const TransactionRecord *wtx) const; QVariant formatTxStatus(const TransactionRecord *wtx) const;
QVariant formatTxDate(const TransactionRecord *wtx) const; QVariant formatTxDate(const TransactionRecord *wtx) const;
QVariant formatTxDescription(const TransactionRecord *wtx) const; QVariant formatTxType(const TransactionRecord *wtx) const;
QVariant formatTxDebit(const TransactionRecord *wtx) const; QVariant formatTxToAddress(const TransactionRecord *wtx) const;
QVariant formatTxCredit(const TransactionRecord *wtx) const; QVariant formatTxAmount(const TransactionRecord *wtx) const;
QVariant formatTxDecoration(const TransactionRecord *wtx) const; QVariant formatTxDecoration(const TransactionRecord *wtx) const;
private slots: private slots: