changeset 1245:6597bf99c530 draft

show last few transactions on overview page
author Wladimir J. van der Laan <laanwj@gmail.com>
date Wed, 03 Aug 2011 20:52:18 +0200
parents 12a1b939263c
children 979c79cb302e
files src/qt/forms/overviewpage.ui src/qt/guiutil.cpp src/qt/guiutil.h src/qt/overviewpage.cpp src/qt/overviewpage.h src/qt/res/icons/tx_inout.png src/qt/res/icons/tx_input.png src/qt/res/icons/tx_mined.png src/qt/res/icons/tx_output.png src/qt/transactionfilterproxy.cpp src/qt/transactionfilterproxy.h src/qt/transactiontablemodel.cpp src/qt/transactiontablemodel.h
diffstat 13 files changed, 269 insertions(+), 77 deletions(-) [+]
line wrap: on
line diff
--- a/src/qt/forms/overviewpage.ui
+++ b/src/qt/forms/overviewpage.ui
@@ -13,82 +13,146 @@
   <property name="windowTitle">
    <string>Form</string>
   </property>
-  <layout class="QVBoxLayout" name="verticalLayout_2">
+  <layout class="QHBoxLayout" name="horizontalLayout" stretch="1,1">
    <item>
-    <widget class="QFrame" name="frame">
-     <property name="frameShape">
-      <enum>QFrame::StyledPanel</enum>
-     </property>
-     <property name="frameShadow">
-      <enum>QFrame::Raised</enum>
-     </property>
-     <layout class="QFormLayout" name="formLayout_2">
-      <property name="fieldGrowthPolicy">
-       <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
-      </property>
-      <property name="horizontalSpacing">
-       <number>12</number>
-      </property>
-      <property name="verticalSpacing">
-       <number>12</number>
-      </property>
-      <item row="0" column="0">
-       <widget class="QLabel" name="label">
-        <property name="text">
-         <string>Balance:</string>
+    <layout class="QVBoxLayout" name="verticalLayout_2">
+     <item>
+      <widget class="QFrame" name="frame">
+       <property name="frameShape">
+        <enum>QFrame::StyledPanel</enum>
+       </property>
+       <property name="frameShadow">
+        <enum>QFrame::Raised</enum>
+       </property>
+       <layout class="QFormLayout" name="formLayout_2">
+        <property name="fieldGrowthPolicy">
+         <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
         </property>
-       </widget>
-      </item>
-      <item row="0" column="1">
-       <widget class="QLabel" name="labelBalance">
-        <property name="text">
-         <string>123.456 BTC</string>
+        <property name="horizontalSpacing">
+         <number>12</number>
+        </property>
+        <property name="verticalSpacing">
+         <number>12</number>
         </property>
-       </widget>
-      </item>
-      <item row="2" column="0">
-       <widget class="QLabel" name="label_2">
-        <property name="text">
-         <string>Number of transactions:</string>
-        </property>
-       </widget>
-      </item>
-      <item row="2" column="1">
-       <widget class="QLabel" name="labelNumTransactions">
-        <property name="text">
-         <string>0</string>
-        </property>
-       </widget>
-      </item>
-      <item row="1" column="0">
-       <widget class="QLabel" name="label_3">
-        <property name="text">
-         <string>Unconfirmed:</string>
-        </property>
-       </widget>
-      </item>
-      <item row="1" column="1">
-       <widget class="QLabel" name="labelUnconfirmed">
-        <property name="text">
-         <string>0 BTC</string>
-        </property>
-       </widget>
-      </item>
-     </layout>
-    </widget>
+        <item row="2" column="0">
+         <widget class="QLabel" name="label">
+          <property name="text">
+           <string>Balance:</string>
+          </property>
+         </widget>
+        </item>
+        <item row="2" column="1">
+         <widget class="QLabel" name="labelBalance">
+          <property name="text">
+           <string>123.456 BTC</string>
+          </property>
+         </widget>
+        </item>
+        <item row="4" column="0">
+         <widget class="QLabel" name="label_2">
+          <property name="text">
+           <string>Number of transactions:</string>
+          </property>
+         </widget>
+        </item>
+        <item row="4" column="1">
+         <widget class="QLabel" name="labelNumTransactions">
+          <property name="text">
+           <string>0</string>
+          </property>
+         </widget>
+        </item>
+        <item row="3" column="0">
+         <widget class="QLabel" name="label_3">
+          <property name="text">
+           <string>Unconfirmed:</string>
+          </property>
+         </widget>
+        </item>
+        <item row="3" column="1">
+         <widget class="QLabel" name="labelUnconfirmed">
+          <property name="text">
+           <string>0 BTC</string>
+          </property>
+         </widget>
+        </item>
+        <item row="1" column="0">
+         <widget class="QLabel" name="label_5">
+          <property name="text">
+           <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
+&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
+p, li { white-space: pre-wrap; }
+&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Ubuntu'; font-size:11pt; font-weight:400; font-style:normal;&quot;&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Wallet&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+          </property>
+         </widget>
+        </item>
+       </layout>
+      </widget>
+     </item>
+     <item>
+      <spacer name="verticalSpacer">
+       <property name="orientation">
+        <enum>Qt::Vertical</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>20</width>
+         <height>40</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
    </item>
    <item>
-    <spacer name="verticalSpacer">
-     <property name="orientation">
-      <enum>Qt::Vertical</enum>
-     </property>
-     <property name="sizeHint" stdset="0">
-      <size>
-       <width>20</width>
-       <height>40</height>
-      </size>
-     </property>
-    </spacer>
+    <layout class="QVBoxLayout" name="verticalLayout_3">
+     <item>
+      <widget class="QFrame" name="frame_2">
+       <property name="frameShape">
+        <enum>QFrame::StyledPanel</enum>
+       </property>
+       <property name="frameShadow">
+        <enum>QFrame::Raised</enum>
+       </property>
+       <layout class="QVBoxLayout" name="verticalLayout">
+        <item>
+         <widget class="QLabel" name="label_4">
+          <property name="text">
+           <string>&lt;b&gt;Recent transactions&lt;/b&gt;</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QListView" name="listTransactions">
+          <property name="frameShape">
+           <enum>QFrame::NoFrame</enum>
+          </property>
+          <property name="verticalScrollBarPolicy">
+           <enum>Qt::ScrollBarAlwaysOff</enum>
+          </property>
+          <property name="horizontalScrollBarPolicy">
+           <enum>Qt::ScrollBarAlwaysOff</enum>
+          </property>
+         </widget>
+        </item>
+       </layout>
+      </widget>
+     </item>
+     <item>
+      <spacer name="verticalSpacer_2">
+       <property name="orientation">
+        <enum>Qt::Vertical</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>20</width>
+         <height>40</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
    </item>
   </layout>
  </widget>
--- 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");
 }
 
--- a/src/qt/guiutil.h
+++ b/src/qt/guiutil.h
@@ -7,12 +7,14 @@
 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();
--- 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 <QDebug>
+#include <QItemDelegate>
+#include <QPainter>
+
+#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<QIcon>(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<QColor>(value))
+        {
+            foreground = qvariant_cast<QColor>(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 @@
 
     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 @@
 {
     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 @@
 {
     if(currentBalance != -1)
         setBalance(currentBalance, currentUnconfirmedBalance);
+
+    txdelegate->unit = model->getOptionsModel()->getDisplayUnit();
+    ui->listTransactions->update();
 }
--- a/src/qt/overviewpage.h
+++ b/src/qt/overviewpage.h
@@ -7,6 +7,7 @@
     class OverviewPage;
 }
 class WalletModel;
+class TxViewDelegate;
 
 class OverviewPage : public QWidget
 {
@@ -28,6 +29,8 @@
     qint64 currentBalance;
     qint64 currentUnconfirmedBalance;
 
+    TxViewDelegate *txdelegate;
+
 private slots:
     void displayUnitChanged();
 };
index ff6bb1c5c3ed6049f5cbde02b95d53e7e4739a2f..5f092f97aa3db749e5e7f490158a489e16cbf4cd
GIT binary patch
literal 2442
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
IM6N<$f*YKb@Bjb+
index 1673d06ad33a333b0a7c6652a30c4e420e933dc2..0f5fea3a8456c73a27c2f0f3d01b3bc96aee389d
GIT binary patch
literal 2152
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
index a336868e8a89b553996f84ad63fba5aba551db06..613f30fecc041468d7ff766236dc509d815f7aab
GIT binary patch
literal 3287
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
VLvj=$Z|eX6002ovPDHLkV1ivBN1Ffu
index 0617239e1436916df96c5cc9cb2b49c738bc6b2d..9ae39fb3291aa0703f045e00b9d640e753dc512d
GIT binary patch
literal 2129
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
Hu0mjf+T;As
--- a/src/qt/transactionfilterproxy.cpp
+++ b/src/qt/transactionfilterproxy.cpp
@@ -15,7 +15,8 @@
     dateTo(MAX_DATE),
     addrPrefix(),
     typeFilter(ALL_TYPES),
-    minAmount(0)
+    minAmount(0),
+    limitRows(-1)
 {
 }
 
@@ -65,3 +66,20 @@
     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);
+    }
+}
--- a/src/qt/transactionfilterproxy.h
+++ b/src/qt/transactionfilterproxy.h
@@ -26,6 +26,10 @@
     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 @@
     QString addrPrefix;
     quint32 typeFilter;
     qint64 minAmount;
+    int limitRows;
 
 signals:
 
--- a/src/qt/transactiontablemodel.cpp
+++ b/src/qt/transactiontablemodel.cpp
@@ -578,6 +578,10 @@
     {
         return llabs(rec->credit + rec->debit);
     }
+    else if (role == AmountRole)
+    {
+        return rec->credit + rec->debit;
+    }
     else if (role == TxIDRole)
     {
         return QString::fromStdString(rec->getTxID());
--- a/src/qt/transactiontablemodel.h
+++ b/src/qt/transactiontablemodel.h
@@ -39,6 +39,8 @@
         LabelRole,
         // Absolute net amount of transaction, for filtering
         AbsoluteAmountRole,
+        // Net amount of transaction
+        AmountRole,
         // Unique identifier
         TxIDRole,
         // Is transaction confirmed?