From 612c497608cc64234a05cd413d4269160f17100c Mon Sep 17 00:00:00 2001 From: Ilya Kitaev Date: Fri, 7 Oct 2016 23:05:51 +0300 Subject: [PATCH] TransactionHistory sorting --- components/HistoryTable.qml | 2 +- main.cpp | 18 ++++-- monero-core.pro | 6 +- pages/History.qml | 49 +++++++++++--- src/libwalletqt/TransactionInfo.cpp | 8 ++- src/libwalletqt/TransactionInfo.h | 6 +- src/libwalletqt/Wallet.cpp | 7 +- src/libwalletqt/Wallet.h | 6 +- src/model/TransactionHistoryModel.cpp | 4 ++ src/model/TransactionHistoryModel.h | 17 ++++- .../TransactionHistorySortFilterModel.cpp | 64 ++++++++++++++++++- src/model/TransactionHistorySortFilterModel.h | 34 ++++++++-- wizard/WizardCreateWallet.qml | 4 +- wizard/WizardManageWalletUI.qml | 2 +- 14 files changed, 191 insertions(+), 36 deletions(-) diff --git a/components/HistoryTable.qml b/components/HistoryTable.qml index 441fbcf5..0cca1148 100644 --- a/components/HistoryTable.qml +++ b/components/HistoryTable.qml @@ -252,7 +252,7 @@ ListView { font.pixelSize: 18 font.letterSpacing: -1 color: isOut ? "#FF4F41" : "#36B05B" - text: amount + text: displayAmount } } } diff --git a/main.cpp b/main.cpp index 9c87628f..58ca60f8 100644 --- a/main.cpp +++ b/main.cpp @@ -42,7 +42,7 @@ #include "TransactionInfo.h" #include "TransactionHistory.h" #include "model/TransactionHistoryModel.h" - +#include "model/TransactionHistorySortFilterModel.h" int main(int argc, char *argv[]) @@ -70,19 +70,23 @@ int main(int argc, char *argv[]) qmlRegisterUncreatableType("moneroComponents.WalletManager", 1, 0, "WalletManager", "WalletManager can't be instantiated directly"); - qmlRegisterUncreatableType("moneroComponents", 1, 0, "TranslationManager", + qmlRegisterUncreatableType("moneroComponents.TranslationManager", 1, 0, "TranslationManager", "TranslationManager can't be instantiated directly"); - qRegisterMetaType(); - - qRegisterMetaType(); - qmlRegisterUncreatableType("moneroComponents", 1, 0, "TransactionHistoryModel", + qmlRegisterUncreatableType("moneroComponents.TransactionHistoryModel", 1, 0, "TransactionHistoryModel", "TransactionHistoryModel can't be instantiated directly"); - qmlRegisterUncreatableType("moneroComponents", 1, 0, "TransactionHistory", + + qmlRegisterUncreatableType("moneroComponents.TransactionHistorySortFilterModel", 1, 0, "TransactionHistorySortFilterModel", + "TransactionHistorySortFilterModel can't be instantiated directly"); + + qmlRegisterUncreatableType("moneroComponents.TransactionHistory", 1, 0, "TransactionHistory", "TransactionHistory can't be instantiated directly"); + qRegisterMetaType(); + qRegisterMetaType(); + qRegisterMetaType(); QQmlApplicationEngine engine; diff --git a/monero-core.pro b/monero-core.pro index 6f21e6ea..daa1378d 100644 --- a/monero-core.pro +++ b/monero-core.pro @@ -24,7 +24,8 @@ HEADERS += \ src/libwalletqt/TransactionInfo.h \ oshelper.h \ TranslationManager.h \ - src/model/TransactionHistoryModel.h + src/model/TransactionHistoryModel.h \ + src/model/TransactionHistorySortFilterModel.h SOURCES += main.cpp \ @@ -38,7 +39,8 @@ SOURCES += main.cpp \ src/libwalletqt/TransactionInfo.cpp \ oshelper.cpp \ TranslationManager.cpp \ - src/model/TransactionHistoryModel.cpp + src/model/TransactionHistoryModel.cpp \ + src/model/TransactionHistorySortFilterModel.cpp lupdate_only { SOURCES = *.qml \ diff --git a/pages/History.qml b/pages/History.qml index d1934629..f8337c5b 100644 --- a/pages/History.qml +++ b/pages/History.qml @@ -27,9 +27,13 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import QtQuick 2.0 -import "../components" + import moneroComponents.Wallet 1.0 import moneroComponents.WalletManager 1.0 +import moneroComponents.TransactionHistory 1.0 +import moneroComponents.TransactionHistoryModel 1.0 + +import "../components" Rectangle { id: root @@ -57,6 +61,8 @@ Rectangle { text: qsTr("Filter transactions history") + translationManager.emptyString } + // Filter by Address input (senseless, removing) + /* Label { id: addressLabel anchors.left: parent.left @@ -77,11 +83,14 @@ Rectangle { anchors.rightMargin: 17 anchors.topMargin: 5 } + */ + + // Filter by Payment ID input Label { id: paymentIdLabel anchors.left: parent.left - anchors.top: addressLine.bottom + anchors.top: filterHeaderText.bottom // addressLine.bottom anchors.leftMargin: 17 anchors.topMargin: 17 text: qsTr("Payment ID (Optional)") + translationManager.emptyString @@ -94,12 +103,14 @@ Rectangle { id: paymentIdLine anchors.left: parent.left anchors.right: parent.right - anchors.top: paymentIdLabel.bottom + anchors.top: paymentIdLabel.bottom // addressLabel.bottom anchors.leftMargin: 17 anchors.rightMargin: 17 anchors.topMargin: 5 } + // Filter by description input (not implemented yet) + /* Label { id: descriptionLabel anchors.left: parent.left @@ -120,11 +131,14 @@ Rectangle { anchors.rightMargin: 17 anchors.topMargin: 5 } + */ + + // DateFrom picker Label { id: dateFromText anchors.left: parent.left - anchors.top: descriptionLine.bottom + anchors.top: paymentIdLine.bottom // descriptionLine.bottom anchors.leftMargin: 17 anchors.topMargin: 17 width: 156 @@ -142,10 +156,11 @@ Rectangle { z: 2 } + // DateTo picker Label { id: dateToText anchors.left: dateFromText.right - anchors.top: descriptionLine.bottom + anchors.top: paymentIdLine.bottom //descriptionLine.bottom anchors.leftMargin: 17 anchors.topMargin: 17 text: qsTr("To") @@ -322,10 +337,11 @@ Rectangle { ListModel { id: columnsModel - ListElement { columnName: "Address"; columnWidth: 127 } + + ListElement { columnName: "Payment ID"; columnWidth: 127 } ListElement { columnName: "Date"; columnWidth: 100 } ListElement { columnName: "Amount"; columnWidth: 148 } - ListElement { columnName: "Description"; columnWidth: 148 } + // ListElement { columnName: "Description"; columnWidth: 148 } } TableHeader { @@ -338,7 +354,24 @@ Rectangle { anchors.rightMargin: 14 dataModel: columnsModel 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 { diff --git a/src/libwalletqt/TransactionInfo.cpp b/src/libwalletqt/TransactionInfo.cpp index 3aa7334c..248fd73e 100644 --- a/src/libwalletqt/TransactionInfo.cpp +++ b/src/libwalletqt/TransactionInfo.cpp @@ -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()); } diff --git a/src/libwalletqt/TransactionInfo.h b/src/libwalletqt/TransactionInfo.h index 3381131a..b614dfc8 100644 --- a/src/libwalletqt/TransactionInfo.h +++ b/src/libwalletqt/TransactionInfo.h @@ -11,7 +11,8 @@ class TransactionInfo : public QObject Q_PROPERTY(Direction direction READ direction) Q_PROPERTY(bool isPending READ isPending) 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(quint64 blockHeight READ blockHeight) Q_PROPERTY(QString hash READ hash) @@ -39,7 +40,8 @@ public: Direction direction() const; bool isPending() const; bool isFailed() const; - QString amount() const; + double amount() const; + QString displayAmount() const; QString fee() const; quint64 blockHeight() const; //! transaction_id diff --git a/src/libwalletqt/Wallet.cpp b/src/libwalletqt/Wallet.cpp index 14e0a868..b52963bc 100644 --- a/src/libwalletqt/Wallet.cpp +++ b/src/libwalletqt/Wallet.cpp @@ -2,6 +2,7 @@ #include "PendingTransaction.h" #include "TransactionHistory.h" #include "model/TransactionHistoryModel.h" +#include "model/TransactionHistorySortFilterModel.h" #include "wallet/wallet2_api.h" #include @@ -213,15 +214,17 @@ TransactionHistory *Wallet::history() const return m_history; } -TransactionHistoryModel *Wallet::historyModel() const +TransactionHistorySortFilterModel *Wallet::historyModel() const { if (!m_historyModel) { Wallet * w = const_cast(this); m_historyModel = new TransactionHistoryModel(w); m_historyModel->setTransactionHistory(this->history()); + m_historySortFilterModel = new TransactionHistorySortFilterModel(w); + m_historySortFilterModel->setSourceModel(m_historyModel); } - return m_historyModel; + return m_historySortFilterModel; } diff --git a/src/libwalletqt/Wallet.h b/src/libwalletqt/Wallet.h index 159a08b0..f9bca5a3 100644 --- a/src/libwalletqt/Wallet.h +++ b/src/libwalletqt/Wallet.h @@ -14,6 +14,7 @@ namespace Bitmonero { class TransactionHistory; class TransactionHistoryModel; +class TransactionHistorySortFilterModel; class Wallet : public QObject { @@ -29,7 +30,7 @@ class Wallet : public QObject Q_PROPERTY(quint64 unlockedBalance READ unlockedBalance) Q_PROPERTY(TransactionHistory * history READ history) Q_PROPERTY(QString paymentId READ paymentId WRITE setPaymentId) - Q_PROPERTY(TransactionHistoryModel * historyModel READ historyModel) + Q_PROPERTY(TransactionHistorySortFilterModel * historyModel READ historyModel) public: @@ -123,7 +124,7 @@ public: TransactionHistory * history() const; //! returns transaction history model - TransactionHistoryModel * historyModel() const; + TransactionHistorySortFilterModel *historyModel() const; //! generate payment id Q_INVOKABLE QString generatePaymentId() const; @@ -165,6 +166,7 @@ private: TransactionHistory * m_history; // Used for UI history view mutable TransactionHistoryModel * m_historyModel; + mutable TransactionHistorySortFilterModel * m_historySortFilterModel; QString m_paymentId; mutable QTime m_daemonBlockChainHeightTime; mutable quint64 m_daemonBlockChainHeight; diff --git a/src/model/TransactionHistoryModel.cpp b/src/model/TransactionHistoryModel.cpp index b8f23f68..1ad17944 100644 --- a/src/model/TransactionHistoryModel.cpp +++ b/src/model/TransactionHistoryModel.cpp @@ -65,6 +65,9 @@ QVariant TransactionHistoryModel::data(const QModelIndex &index, int role) const case TransactionAmountRole: result = tInfo->amount(); break; + case TransactionDisplayAmountRole: + result = tInfo->displayAmount(); + break; case TransactionFeeRole: result = tInfo->fee(); break; @@ -108,6 +111,7 @@ QHash TransactionHistoryModel::roleNames() const roleNames.insert(TransactionPendingRole, "isPending"); roleNames.insert(TransactionFailedRole, "isFailed"); roleNames.insert(TransactionAmountRole, "amount"); + roleNames.insert(TransactionDisplayAmountRole, "displayAmount"); roleNames.insert(TransactionFeeRole, "fee"); roleNames.insert(TransactionBlockHeightRole, "blockHeight"); roleNames.insert(TransactionHashRole, "hash"); diff --git a/src/model/TransactionHistoryModel.h b/src/model/TransactionHistoryModel.h index 96d3ff32..0960ceae 100644 --- a/src/model/TransactionHistoryModel.h +++ b/src/model/TransactionHistoryModel.h @@ -9,6 +9,7 @@ class TransactionInfo; /** * @brief The TransactionHistoryModel class - read-only list model for Transaction History */ + class TransactionHistoryModel : public QAbstractListModel { Q_OBJECT @@ -21,6 +22,7 @@ public: TransactionPendingRole, TransactionFailedRole, TransactionAmountRole, + TransactionDisplayAmountRole, TransactionFeeRole, TransactionBlockHeightRole, TransactionHashRole, @@ -32,10 +34,24 @@ public: TransactionDateRole, TransactionTimeRole }; + Q_ENUM(TransactionInfoRole) TransactionHistoryModel(QObject * parent = 0); void setTransactionHistory(TransactionHistory * th); TransactionHistory * transactionHistory() const; + /** + * @brief dateFrom - returns firstmost transaction datetime + * @return + */ + QDateTime firstDateTime() const; + + /** + * @brief dateTo - returns lastmost transaction datetime + * @return + */ + QDateTime lastDateTime() const; + + /// QAbstractListModel virtual QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override; @@ -47,7 +63,6 @@ signals: private: TransactionHistory * m_transactionHistory; - }; #endif // TRANSACTIONHISTORYMODEL_H diff --git a/src/model/TransactionHistorySortFilterModel.cpp b/src/model/TransactionHistorySortFilterModel.cpp index 67d7b84a..946137c6 100644 --- a/src/model/TransactionHistorySortFilterModel.cpp +++ b/src/model/TransactionHistorySortFilterModel.cpp @@ -1,6 +1,66 @@ -#include "TransactionHistorySortFiltrerModel.h" +#include "TransactionHistorySortFilterModel.h" +#include "TransactionHistoryModel.h" -TransactionHistorySortFiltrerModel::TransactionHistorySortFiltrerModel() +#include + +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; +} diff --git a/src/model/TransactionHistorySortFilterModel.h b/src/model/TransactionHistorySortFilterModel.h index bdcab079..c1d3d2c2 100644 --- a/src/model/TransactionHistorySortFilterModel.h +++ b/src/model/TransactionHistorySortFilterModel.h @@ -1,12 +1,34 @@ -#ifndef TRANSACTIONHISTORYSORTFILTRERMODEL_H -#define TRANSACTIONHISTORYSORTFILTRERMODEL_H +#ifndef TRANSACTIONHISTORYSORTFILTERMODEL_H +#define TRANSACTIONHISTORYSORTFILTERMODEL_H -#include -class TransactionHistorySortFiltrerModel : public QSortFilterProxyModel +#include +#include +#include + + +class TransactionHistorySortFilterModel: public QSortFilterProxyModel { +Q_OBJECT 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 m_filterValues; }; -#endif // TRANSACTIONHISTORYSORTFILTRERMODEL_H \ No newline at end of file +#endif // TRANSACTIONHISTORYSORTFILTERMODEL_H diff --git a/wizard/WizardCreateWallet.qml b/wizard/WizardCreateWallet.qml index f0344a94..8506a8e7 100644 --- a/wizard/WizardCreateWallet.qml +++ b/wizard/WizardCreateWallet.qml @@ -27,7 +27,9 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import QtQuick 2.2 -import moneroComponents 1.0 +import moneroComponents.WalletManager 1.0 +import moneroComponents.Wallet 1.0 + import QtQuick.Dialogs 1.2 import 'utils.js' as Utils diff --git a/wizard/WizardManageWalletUI.qml b/wizard/WizardManageWalletUI.qml index cc8a5be3..ede68b13 100644 --- a/wizard/WizardManageWalletUI.qml +++ b/wizard/WizardManageWalletUI.qml @@ -27,7 +27,7 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import QtQuick 2.2 -import moneroComponents 1.0 +import moneroComponents.TranslationManager 1.0 import QtQuick.Dialogs 1.2 // Reusable component for managing wallet (account name, path, private key)