diff --git a/src/qt/forms/overviewpage.ui b/src/qt/forms/overviewpage.ui index d8362a7b..cc67fae5 100644 --- a/src/qt/forms/overviewpage.ui +++ b/src/qt/forms/overviewpage.ui @@ -13,82 +13,146 @@ Form - + - - - QFrame::StyledPanel - - - QFrame::Raised - - - - QFormLayout::AllNonFixedFieldsGrow - - - 12 - - - 12 - - - - - Balance: + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + QFormLayout::AllNonFixedFieldsGrow - - - - - - 123.456 BTC + + 12 - - - - - - Number of transactions: + + 12 - - - - - - 0 - - - - - - - Unconfirmed: - - - - - - - 0 BTC - - - - - + + + + Balance: + + + + + + + 123.456 BTC + + + + + + + Number of transactions: + + + + + + + 0 + + + + + + + Unconfirmed: + + + + + + + 0 BTC + + + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Wallet</span></p></body></html> + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + - - - Qt::Vertical - - - - 20 - 40 - - - + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + <b>Recent transactions</b> + + + + + + + QFrame::NoFrame + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOff + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index 308a6ba9..ece06907 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -11,7 +11,11 @@ QString GUIUtil::DateTimeStr(qint64 nTime) { - QDateTime date = QDateTime::fromTime_t((qint32)nTime); + return DateTimeStr(QDateTime::fromTime_t((qint32)nTime)); +} + +QString GUIUtil::DateTimeStr(const QDateTime &date) +{ return date.date().toString(Qt::SystemLocaleShortDate) + QString(" ") + date.toString("hh:mm"); } diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h index 26a1a037..fb5c575a 100644 --- a/src/qt/guiutil.h +++ b/src/qt/guiutil.h @@ -7,12 +7,14 @@ QT_BEGIN_NAMESPACE class QFont; class QLineEdit; class QWidget; +class QDateTime; QT_END_NAMESPACE class GUIUtil { public: static QString DateTimeStr(qint64 nTime); + static QString DateTimeStr(const QDateTime &datetime); // Render bitcoin addresses in monospace font static QFont bitcoinAddressFont(); diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index c04bbf60..f79e1f3e 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -4,14 +4,87 @@ #include "walletmodel.h" #include "bitcoinunits.h" #include "optionsmodel.h" +#include "transactiontablemodel.h" +#include "transactionfilterproxy.h" +#include "guiutil.h" +#include "guiconstants.h" #include +#include +#include + +#define DECORATION_SIZE 64 +class TxViewDelegate : public QItemDelegate +{ + //Q_OBJECT +public: + TxViewDelegate(): QItemDelegate(), unit(BitcoinUnits::BTC) + { + + } + + inline void paint(QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index ) const + { + //QItemDelegate::paint(painter, option, index); + painter->save(); + + QIcon icon = qvariant_cast(index.data(Qt::DecorationRole)); + QRect mainRect = option.rect; + QRect decorationRect(mainRect.topLeft(), QSize(DECORATION_SIZE, DECORATION_SIZE)); + int xspace = DECORATION_SIZE + 8; + int ypad = 6; + int halfheight = (mainRect.height() - 2*ypad)/2; + QRect amountRect(mainRect.left() + xspace, mainRect.top()+ypad, mainRect.width() - xspace, halfheight); + QRect addressRect(mainRect.left() + xspace, mainRect.top()+ypad+halfheight, mainRect.width() - xspace, halfheight); + icon.paint(painter, decorationRect); + + QDateTime date = index.data(TransactionTableModel::DateRole).toDateTime(); + QString address = index.data(Qt::DisplayRole).toString(); + qint64 amount = index.data(TransactionTableModel::AmountRole).toLongLong(); + bool confirmed = index.data(TransactionTableModel::ConfirmedRole).toBool(); + QVariant value = index.data(Qt::ForegroundRole); + QColor foreground = option.palette.color(QPalette::Text); + if(qVariantCanConvert(value)) + { + foreground = qvariant_cast(value); + } + + painter->setPen(foreground); + painter->drawText(addressRect, Qt::AlignLeft|Qt::AlignVCenter, address); + + if(amount < 0) + { + foreground = COLOR_NEGATIVE; + } + else + { + foreground = option.palette.color(QPalette::Text); + } + painter->setPen(foreground); + QString amountText = BitcoinUnits::formatWithUnit(unit, amount, true); + if(!confirmed) + { + amountText = QString("[") + amountText + QString("]"); + } + painter->drawText(amountRect, Qt::AlignRight|Qt::AlignVCenter, amountText); + + painter->setPen(option.palette.color(QPalette::Text)); + painter->drawText(amountRect, Qt::AlignLeft|Qt::AlignVCenter, GUIUtil::DateTimeStr(date)); + + painter->restore(); + } + + int unit; + +}; OverviewPage::OverviewPage(QWidget *parent) : QWidget(parent), ui(new Ui::OverviewPage), currentBalance(-1), - currentUnconfirmedBalance(-1) + currentUnconfirmedBalance(-1), + txdelegate(new TxViewDelegate()) { ui->setupUi(this); @@ -27,9 +100,11 @@ OverviewPage::OverviewPage(QWidget *parent) : ui->labelNumTransactions->setToolTip(tr("Total number of transactions in wallet")); - // Overview page should show: - // Last received transaction(s) - // Last sent transaction(s) + // Recent transactions + ui->listTransactions->setStyleSheet("background:transparent"); + ui->listTransactions->setItemDelegate(txdelegate); + ui->listTransactions->setIconSize(QSize(DECORATION_SIZE, DECORATION_SIZE)); + ui->listTransactions->setSelectionMode(QAbstractItemView::NoSelection); } OverviewPage::~OverviewPage() @@ -55,6 +130,18 @@ void OverviewPage::setModel(WalletModel *model) { this->model = model; + // Set up transaction list + + TransactionFilterProxy *filter = new TransactionFilterProxy(); + filter->setSourceModel(model->getTransactionTableModel()); + filter->setLimit(3); + filter->setDynamicSortFilter(true); + filter->setSortRole(Qt::EditRole); + filter->sort(TransactionTableModel::Status, Qt::DescendingOrder); + + ui->listTransactions->setModel(filter); + ui->listTransactions->setModelColumn(TransactionTableModel::ToAddress); + // Keep up to date with wallet setBalance(model->getBalance(), model->getUnconfirmedBalance()); connect(model, SIGNAL(balanceChanged(qint64, qint64)), this, SLOT(setBalance(qint64, qint64))); @@ -69,4 +156,7 @@ void OverviewPage::displayUnitChanged() { if(currentBalance != -1) setBalance(currentBalance, currentUnconfirmedBalance); + + txdelegate->unit = model->getOptionsModel()->getDisplayUnit(); + ui->listTransactions->update(); } diff --git a/src/qt/overviewpage.h b/src/qt/overviewpage.h index c54dda32..2abddf16 100644 --- a/src/qt/overviewpage.h +++ b/src/qt/overviewpage.h @@ -7,6 +7,7 @@ namespace Ui { class OverviewPage; } class WalletModel; +class TxViewDelegate; class OverviewPage : public QWidget { @@ -28,6 +29,8 @@ private: qint64 currentBalance; qint64 currentUnconfirmedBalance; + TxViewDelegate *txdelegate; + private slots: void displayUnitChanged(); }; diff --git a/src/qt/res/icons/tx_inout.png b/src/qt/res/icons/tx_inout.png index ff6bb1c5..5f092f97 100644 Binary files a/src/qt/res/icons/tx_inout.png and b/src/qt/res/icons/tx_inout.png differ diff --git a/src/qt/res/icons/tx_input.png b/src/qt/res/icons/tx_input.png index 1673d06a..0f5fea3a 100644 Binary files a/src/qt/res/icons/tx_input.png and b/src/qt/res/icons/tx_input.png differ diff --git a/src/qt/res/icons/tx_mined.png b/src/qt/res/icons/tx_mined.png index a336868e..613f30fe 100644 Binary files a/src/qt/res/icons/tx_mined.png and b/src/qt/res/icons/tx_mined.png differ diff --git a/src/qt/res/icons/tx_output.png b/src/qt/res/icons/tx_output.png index 0617239e..9ae39fb3 100644 Binary files a/src/qt/res/icons/tx_output.png and b/src/qt/res/icons/tx_output.png differ diff --git a/src/qt/transactionfilterproxy.cpp b/src/qt/transactionfilterproxy.cpp index cd1194d9..5a66f851 100644 --- a/src/qt/transactionfilterproxy.cpp +++ b/src/qt/transactionfilterproxy.cpp @@ -15,7 +15,8 @@ TransactionFilterProxy::TransactionFilterProxy(QObject *parent) : dateTo(MAX_DATE), addrPrefix(), typeFilter(ALL_TYPES), - minAmount(0) + minAmount(0), + limitRows(-1) { } @@ -65,3 +66,20 @@ void TransactionFilterProxy::setMinAmount(qint64 minimum) this->minAmount = minimum; invalidateFilter(); } + +void TransactionFilterProxy::setLimit(int limit) +{ + this->limitRows = limit; +} + +int TransactionFilterProxy::rowCount(const QModelIndex &parent) const +{ + if(limitRows != -1) + { + return std::min(QSortFilterProxyModel::rowCount(parent), limitRows); + } + else + { + return QSortFilterProxyModel::rowCount(parent); + } +} diff --git a/src/qt/transactionfilterproxy.h b/src/qt/transactionfilterproxy.h index a44c9c4d..4dd2a8e5 100644 --- a/src/qt/transactionfilterproxy.h +++ b/src/qt/transactionfilterproxy.h @@ -26,6 +26,10 @@ public: void setTypeFilter(quint32 modes); void setMinAmount(qint64 minimum); + // Set maximum number of rows returned, -1 if unlimited + void setLimit(int limit); + + int rowCount(const QModelIndex &parent = QModelIndex()) const; protected: bool filterAcceptsRow(int source_row, const QModelIndex & source_parent) const; @@ -35,6 +39,7 @@ private: QString addrPrefix; quint32 typeFilter; qint64 minAmount; + int limitRows; signals: diff --git a/src/qt/transactiontablemodel.cpp b/src/qt/transactiontablemodel.cpp index 1606df9f..458341c0 100644 --- a/src/qt/transactiontablemodel.cpp +++ b/src/qt/transactiontablemodel.cpp @@ -578,6 +578,10 @@ QVariant TransactionTableModel::data(const QModelIndex &index, int role) const { return llabs(rec->credit + rec->debit); } + else if (role == AmountRole) + { + return rec->credit + rec->debit; + } else if (role == TxIDRole) { return QString::fromStdString(rec->getTxID()); diff --git a/src/qt/transactiontablemodel.h b/src/qt/transactiontablemodel.h index 71b06441..0daa5f6a 100644 --- a/src/qt/transactiontablemodel.h +++ b/src/qt/transactiontablemodel.h @@ -39,6 +39,8 @@ public: LabelRole, // Absolute net amount of transaction, for filtering AbsoluteAmountRole, + // Net amount of transaction + AmountRole, // Unique identifier TxIDRole, // Is transaction confirmed?