TransactionHistory sorting

This commit is contained in:
Ilya Kitaev 2016-10-07 23:05:51 +03:00
parent e7e6c583b6
commit 612c497608
14 changed files with 191 additions and 36 deletions

View file

@ -252,7 +252,7 @@ ListView {
font.pixelSize: 18 font.pixelSize: 18
font.letterSpacing: -1 font.letterSpacing: -1
color: isOut ? "#FF4F41" : "#36B05B" color: isOut ? "#FF4F41" : "#36B05B"
text: amount text: displayAmount
} }
} }
} }

View file

@ -42,7 +42,7 @@
#include "TransactionInfo.h" #include "TransactionInfo.h"
#include "TransactionHistory.h" #include "TransactionHistory.h"
#include "model/TransactionHistoryModel.h" #include "model/TransactionHistoryModel.h"
#include "model/TransactionHistorySortFilterModel.h"
int main(int argc, char *argv[]) int main(int argc, char *argv[])
@ -70,19 +70,23 @@ int main(int argc, char *argv[])
qmlRegisterUncreatableType<WalletManager>("moneroComponents.WalletManager", 1, 0, "WalletManager", qmlRegisterUncreatableType<WalletManager>("moneroComponents.WalletManager", 1, 0, "WalletManager",
"WalletManager can't be instantiated directly"); "WalletManager can't be instantiated directly");
qmlRegisterUncreatableType<TranslationManager>("moneroComponents", 1, 0, "TranslationManager", qmlRegisterUncreatableType<TranslationManager>("moneroComponents.TranslationManager", 1, 0, "TranslationManager",
"TranslationManager can't be instantiated directly"); "TranslationManager can't be instantiated directly");
qRegisterMetaType<PendingTransaction::Priority>();
qRegisterMetaType<TransactionInfo::Direction>();
qmlRegisterUncreatableType<TransactionHistoryModel>("moneroComponents", 1, 0, "TransactionHistoryModel", qmlRegisterUncreatableType<TransactionHistoryModel>("moneroComponents.TransactionHistoryModel", 1, 0, "TransactionHistoryModel",
"TransactionHistoryModel can't be instantiated directly"); "TransactionHistoryModel can't be instantiated directly");
qmlRegisterUncreatableType<TransactionHistory>("moneroComponents", 1, 0, "TransactionHistory",
qmlRegisterUncreatableType<TransactionHistorySortFilterModel>("moneroComponents.TransactionHistorySortFilterModel", 1, 0, "TransactionHistorySortFilterModel",
"TransactionHistorySortFilterModel can't be instantiated directly");
qmlRegisterUncreatableType<TransactionHistory>("moneroComponents.TransactionHistory", 1, 0, "TransactionHistory",
"TransactionHistory can't be instantiated directly"); "TransactionHistory can't be instantiated directly");
qRegisterMetaType<PendingTransaction::Priority>();
qRegisterMetaType<TransactionInfo::Direction>();
qRegisterMetaType<TransactionHistoryModel::TransactionInfoRole>();
QQmlApplicationEngine engine; QQmlApplicationEngine engine;

View file

@ -24,7 +24,8 @@ HEADERS += \
src/libwalletqt/TransactionInfo.h \ src/libwalletqt/TransactionInfo.h \
oshelper.h \ oshelper.h \
TranslationManager.h \ TranslationManager.h \
src/model/TransactionHistoryModel.h src/model/TransactionHistoryModel.h \
src/model/TransactionHistorySortFilterModel.h
SOURCES += main.cpp \ SOURCES += main.cpp \
@ -38,7 +39,8 @@ SOURCES += main.cpp \
src/libwalletqt/TransactionInfo.cpp \ src/libwalletqt/TransactionInfo.cpp \
oshelper.cpp \ oshelper.cpp \
TranslationManager.cpp \ TranslationManager.cpp \
src/model/TransactionHistoryModel.cpp src/model/TransactionHistoryModel.cpp \
src/model/TransactionHistorySortFilterModel.cpp
lupdate_only { lupdate_only {
SOURCES = *.qml \ SOURCES = *.qml \

View file

@ -27,9 +27,13 @@
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import QtQuick 2.0 import QtQuick 2.0
import "../components"
import moneroComponents.Wallet 1.0 import moneroComponents.Wallet 1.0
import moneroComponents.WalletManager 1.0 import moneroComponents.WalletManager 1.0
import moneroComponents.TransactionHistory 1.0
import moneroComponents.TransactionHistoryModel 1.0
import "../components"
Rectangle { Rectangle {
id: root id: root
@ -57,6 +61,8 @@ Rectangle {
text: qsTr("Filter transactions history") + translationManager.emptyString text: qsTr("Filter transactions history") + translationManager.emptyString
} }
// Filter by Address input (senseless, removing)
/*
Label { Label {
id: addressLabel id: addressLabel
anchors.left: parent.left anchors.left: parent.left
@ -77,11 +83,14 @@ Rectangle {
anchors.rightMargin: 17 anchors.rightMargin: 17
anchors.topMargin: 5 anchors.topMargin: 5
} }
*/
// Filter by Payment ID input
Label { Label {
id: paymentIdLabel id: paymentIdLabel
anchors.left: parent.left anchors.left: parent.left
anchors.top: addressLine.bottom anchors.top: filterHeaderText.bottom // addressLine.bottom
anchors.leftMargin: 17 anchors.leftMargin: 17
anchors.topMargin: 17 anchors.topMargin: 17
text: qsTr("Payment ID <font size='2'>(Optional)</font>") + translationManager.emptyString text: qsTr("Payment ID <font size='2'>(Optional)</font>") + translationManager.emptyString
@ -94,12 +103,14 @@ Rectangle {
id: paymentIdLine id: paymentIdLine
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
anchors.top: paymentIdLabel.bottom anchors.top: paymentIdLabel.bottom // addressLabel.bottom
anchors.leftMargin: 17 anchors.leftMargin: 17
anchors.rightMargin: 17 anchors.rightMargin: 17
anchors.topMargin: 5 anchors.topMargin: 5
} }
// Filter by description input (not implemented yet)
/*
Label { Label {
id: descriptionLabel id: descriptionLabel
anchors.left: parent.left anchors.left: parent.left
@ -120,11 +131,14 @@ Rectangle {
anchors.rightMargin: 17 anchors.rightMargin: 17
anchors.topMargin: 5 anchors.topMargin: 5
} }
*/
// DateFrom picker
Label { Label {
id: dateFromText id: dateFromText
anchors.left: parent.left anchors.left: parent.left
anchors.top: descriptionLine.bottom anchors.top: paymentIdLine.bottom // descriptionLine.bottom
anchors.leftMargin: 17 anchors.leftMargin: 17
anchors.topMargin: 17 anchors.topMargin: 17
width: 156 width: 156
@ -142,10 +156,11 @@ Rectangle {
z: 2 z: 2
} }
// DateTo picker
Label { Label {
id: dateToText id: dateToText
anchors.left: dateFromText.right anchors.left: dateFromText.right
anchors.top: descriptionLine.bottom anchors.top: paymentIdLine.bottom //descriptionLine.bottom
anchors.leftMargin: 17 anchors.leftMargin: 17
anchors.topMargin: 17 anchors.topMargin: 17
text: qsTr("To") text: qsTr("To")
@ -322,10 +337,11 @@ Rectangle {
ListModel { ListModel {
id: columnsModel id: columnsModel
ListElement { columnName: "Address"; columnWidth: 127 }
ListElement { columnName: "Payment ID"; columnWidth: 127 }
ListElement { columnName: "Date"; columnWidth: 100 } ListElement { columnName: "Date"; columnWidth: 100 }
ListElement { columnName: "Amount"; columnWidth: 148 } ListElement { columnName: "Amount"; columnWidth: 148 }
ListElement { columnName: "Description"; columnWidth: 148 } // ListElement { columnName: "Description"; columnWidth: 148 }
} }
TableHeader { TableHeader {
@ -338,7 +354,24 @@ Rectangle {
anchors.rightMargin: 14 anchors.rightMargin: 14
dataModel: columnsModel dataModel: columnsModel
offset: 20 offset: 20
onSortRequest: console.log("column: " + column + " desc: " + desc) onSortRequest: {
console.log("column: " + column + " desc: " + desc)
switch (column) {
case 0:
// Payment ID
model.sortRole = TransactionHistoryModel.TransactionPaymentIdRole
break;
case 1:
// Date;
model.sortRole = TransactionHistoryModel.TransactionDateRole
break;
case 2:
// Amount;
model.sortRole = TransactionHistoryModel.TransactionAmountRole
break;
}
model.sort(0, desc ? Qt.DescendingOrder : Qt.AscendingOrder)
}
} }
/* /*
ListModel { ListModel {

View file

@ -19,7 +19,13 @@ bool TransactionInfo::isFailed() const
} }
QString TransactionInfo::amount() const double TransactionInfo::amount() const
{
// there's no unsigned uint64 for JS, so better use double
return WalletManager::instance()->displayAmount(m_pimpl->amount()).toDouble();
}
QString TransactionInfo::displayAmount() const
{ {
return WalletManager::instance()->displayAmount(m_pimpl->amount()); return WalletManager::instance()->displayAmount(m_pimpl->amount());
} }

View file

@ -11,7 +11,8 @@ class TransactionInfo : public QObject
Q_PROPERTY(Direction direction READ direction) Q_PROPERTY(Direction direction READ direction)
Q_PROPERTY(bool isPending READ isPending) Q_PROPERTY(bool isPending READ isPending)
Q_PROPERTY(bool isFailed READ isFailed) Q_PROPERTY(bool isFailed READ isFailed)
Q_PROPERTY(QString amount READ amount) Q_PROPERTY(double amount READ amount)
Q_PROPERTY(QString displayAmount READ displayAmount)
Q_PROPERTY(QString fee READ fee) Q_PROPERTY(QString fee READ fee)
Q_PROPERTY(quint64 blockHeight READ blockHeight) Q_PROPERTY(quint64 blockHeight READ blockHeight)
Q_PROPERTY(QString hash READ hash) Q_PROPERTY(QString hash READ hash)
@ -39,7 +40,8 @@ public:
Direction direction() const; Direction direction() const;
bool isPending() const; bool isPending() const;
bool isFailed() const; bool isFailed() const;
QString amount() const; double amount() const;
QString displayAmount() const;
QString fee() const; QString fee() const;
quint64 blockHeight() const; quint64 blockHeight() const;
//! transaction_id //! transaction_id

View file

@ -2,6 +2,7 @@
#include "PendingTransaction.h" #include "PendingTransaction.h"
#include "TransactionHistory.h" #include "TransactionHistory.h"
#include "model/TransactionHistoryModel.h" #include "model/TransactionHistoryModel.h"
#include "model/TransactionHistorySortFilterModel.h"
#include "wallet/wallet2_api.h" #include "wallet/wallet2_api.h"
#include <QFile> #include <QFile>
@ -213,15 +214,17 @@ TransactionHistory *Wallet::history() const
return m_history; return m_history;
} }
TransactionHistoryModel *Wallet::historyModel() const TransactionHistorySortFilterModel *Wallet::historyModel() const
{ {
if (!m_historyModel) { if (!m_historyModel) {
Wallet * w = const_cast<Wallet*>(this); Wallet * w = const_cast<Wallet*>(this);
m_historyModel = new TransactionHistoryModel(w); m_historyModel = new TransactionHistoryModel(w);
m_historyModel->setTransactionHistory(this->history()); m_historyModel->setTransactionHistory(this->history());
m_historySortFilterModel = new TransactionHistorySortFilterModel(w);
m_historySortFilterModel->setSourceModel(m_historyModel);
} }
return m_historyModel; return m_historySortFilterModel;
} }

View file

@ -14,6 +14,7 @@ namespace Bitmonero {
class TransactionHistory; class TransactionHistory;
class TransactionHistoryModel; class TransactionHistoryModel;
class TransactionHistorySortFilterModel;
class Wallet : public QObject class Wallet : public QObject
{ {
@ -29,7 +30,7 @@ class Wallet : public QObject
Q_PROPERTY(quint64 unlockedBalance READ unlockedBalance) Q_PROPERTY(quint64 unlockedBalance READ unlockedBalance)
Q_PROPERTY(TransactionHistory * history READ history) Q_PROPERTY(TransactionHistory * history READ history)
Q_PROPERTY(QString paymentId READ paymentId WRITE setPaymentId) Q_PROPERTY(QString paymentId READ paymentId WRITE setPaymentId)
Q_PROPERTY(TransactionHistoryModel * historyModel READ historyModel) Q_PROPERTY(TransactionHistorySortFilterModel * historyModel READ historyModel)
public: public:
@ -123,7 +124,7 @@ public:
TransactionHistory * history() const; TransactionHistory * history() const;
//! returns transaction history model //! returns transaction history model
TransactionHistoryModel * historyModel() const; TransactionHistorySortFilterModel *historyModel() const;
//! generate payment id //! generate payment id
Q_INVOKABLE QString generatePaymentId() const; Q_INVOKABLE QString generatePaymentId() const;
@ -165,6 +166,7 @@ private:
TransactionHistory * m_history; TransactionHistory * m_history;
// Used for UI history view // Used for UI history view
mutable TransactionHistoryModel * m_historyModel; mutable TransactionHistoryModel * m_historyModel;
mutable TransactionHistorySortFilterModel * m_historySortFilterModel;
QString m_paymentId; QString m_paymentId;
mutable QTime m_daemonBlockChainHeightTime; mutable QTime m_daemonBlockChainHeightTime;
mutable quint64 m_daemonBlockChainHeight; mutable quint64 m_daemonBlockChainHeight;

View file

@ -65,6 +65,9 @@ QVariant TransactionHistoryModel::data(const QModelIndex &index, int role) const
case TransactionAmountRole: case TransactionAmountRole:
result = tInfo->amount(); result = tInfo->amount();
break; break;
case TransactionDisplayAmountRole:
result = tInfo->displayAmount();
break;
case TransactionFeeRole: case TransactionFeeRole:
result = tInfo->fee(); result = tInfo->fee();
break; break;
@ -108,6 +111,7 @@ QHash<int, QByteArray> TransactionHistoryModel::roleNames() const
roleNames.insert(TransactionPendingRole, "isPending"); roleNames.insert(TransactionPendingRole, "isPending");
roleNames.insert(TransactionFailedRole, "isFailed"); roleNames.insert(TransactionFailedRole, "isFailed");
roleNames.insert(TransactionAmountRole, "amount"); roleNames.insert(TransactionAmountRole, "amount");
roleNames.insert(TransactionDisplayAmountRole, "displayAmount");
roleNames.insert(TransactionFeeRole, "fee"); roleNames.insert(TransactionFeeRole, "fee");
roleNames.insert(TransactionBlockHeightRole, "blockHeight"); roleNames.insert(TransactionBlockHeightRole, "blockHeight");
roleNames.insert(TransactionHashRole, "hash"); roleNames.insert(TransactionHashRole, "hash");

View file

@ -9,6 +9,7 @@ class TransactionInfo;
/** /**
* @brief The TransactionHistoryModel class - read-only list model for Transaction History * @brief The TransactionHistoryModel class - read-only list model for Transaction History
*/ */
class TransactionHistoryModel : public QAbstractListModel class TransactionHistoryModel : public QAbstractListModel
{ {
Q_OBJECT Q_OBJECT
@ -21,6 +22,7 @@ public:
TransactionPendingRole, TransactionPendingRole,
TransactionFailedRole, TransactionFailedRole,
TransactionAmountRole, TransactionAmountRole,
TransactionDisplayAmountRole,
TransactionFeeRole, TransactionFeeRole,
TransactionBlockHeightRole, TransactionBlockHeightRole,
TransactionHashRole, TransactionHashRole,
@ -32,10 +34,24 @@ public:
TransactionDateRole, TransactionDateRole,
TransactionTimeRole TransactionTimeRole
}; };
Q_ENUM(TransactionInfoRole)
TransactionHistoryModel(QObject * parent = 0); TransactionHistoryModel(QObject * parent = 0);
void setTransactionHistory(TransactionHistory * th); void setTransactionHistory(TransactionHistory * th);
TransactionHistory * transactionHistory() const; TransactionHistory * transactionHistory() const;
/**
* @brief dateFrom - returns firstmost transaction datetime
* @return
*/
QDateTime firstDateTime() const;
/**
* @brief dateTo - returns lastmost transaction datetime
* @return
*/
QDateTime lastDateTime() const;
/// QAbstractListModel /// QAbstractListModel
virtual QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override; virtual QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override;
@ -47,7 +63,6 @@ signals:
private: private:
TransactionHistory * m_transactionHistory; TransactionHistory * m_transactionHistory;
}; };
#endif // TRANSACTIONHISTORYMODEL_H #endif // TRANSACTIONHISTORYMODEL_H

View file

@ -1,6 +1,66 @@
#include "TransactionHistorySortFiltrerModel.h" #include "TransactionHistorySortFilterModel.h"
#include "TransactionHistoryModel.h"
TransactionHistorySortFiltrerModel::TransactionHistorySortFiltrerModel() #include <QDebug>
TransactionHistorySortFilterModel::TransactionHistorySortFilterModel(QObject *parent)
: QSortFilterProxyModel(parent)
{ {
} }
QString TransactionHistorySortFilterModel::paymentIdFilter() const
{
}
void TransactionHistorySortFilterModel::setPaymentIdFilter(const QString &arg)
{
}
void TransactionHistorySortFilterModel::sort(int column, Qt::SortOrder order)
{
QSortFilterProxyModel::sort(column, order);
}
bool TransactionHistorySortFilterModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
{
if (source_row < 0 || source_row >= sourceModel()->rowCount()) {
return false;
}
QModelIndex index = sourceModel()->index(source_row, 0, source_parent);
if (!index.isValid()) {
return false;
}
bool result = true;
for (int role : m_filterValues.keys()) {
if (m_filterValues.contains(role)) {
QVariant data = sourceModel()->data(index, role);
result = data.toString().contains(m_filterValues.value(role).toString());
if (result)
break;
}
}
return result;
}
bool TransactionHistorySortFilterModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
{
return QSortFilterProxyModel::lessThan(source_left, source_right);
}
QVariant TransactionHistorySortFilterModel::filterValue(int role)
{
return m_filterValues.value(role);
}
void TransactionHistorySortFilterModel::setFilterValue(int role, const QVariant &filterValue)
{
m_filterValues[role] = filterValue;
}

View file

@ -1,12 +1,34 @@
#ifndef TRANSACTIONHISTORYSORTFILTRERMODEL_H #ifndef TRANSACTIONHISTORYSORTFILTERMODEL_H
#define TRANSACTIONHISTORYSORTFILTRERMODEL_H #define TRANSACTIONHISTORYSORTFILTERMODEL_H
#include <QObject>
class TransactionHistorySortFiltrerModel : public QSortFilterProxyModel #include <QSortFilterProxyModel>
#include <QMap>
#include <QVariant>
class TransactionHistorySortFilterModel: public QSortFilterProxyModel
{ {
Q_OBJECT
public: public:
TransactionHistorySortFiltrerModel(); TransactionHistorySortFilterModel(QObject * parent = nullptr);
QString paymentIdFilter() const;
void setPaymentIdFilter(const QString &arg);
Q_INVOKABLE void sort(int column, Qt::SortOrder order);
protected:
// QSortFilterProxyModel overrides
virtual bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const;
virtual bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const;
private:
QVariant filterValue(int role);
void setFilterValue(int role, const QVariant &filterValue);
private:
QMap<int, QVariant> m_filterValues;
}; };
#endif // TRANSACTIONHISTORYSORTFILTRERMODEL_H #endif // TRANSACTIONHISTORYSORTFILTERMODEL_H

View file

@ -27,7 +27,9 @@
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import QtQuick 2.2 import QtQuick 2.2
import moneroComponents 1.0 import moneroComponents.WalletManager 1.0
import moneroComponents.Wallet 1.0
import QtQuick.Dialogs 1.2 import QtQuick.Dialogs 1.2
import 'utils.js' as Utils import 'utils.js' as Utils

View file

@ -27,7 +27,7 @@
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import QtQuick 2.2 import QtQuick 2.2
import moneroComponents 1.0 import moneroComponents.TranslationManager 1.0
import QtQuick.Dialogs 1.2 import QtQuick.Dialogs 1.2
// Reusable component for managing wallet (account name, path, private key) // Reusable component for managing wallet (account name, path, private key)