From 0ff3fd32122a22d7c56a289faa6402351f425873 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev Date: Sun, 2 Oct 2016 21:40:40 +0300 Subject: [PATCH] added TransactionHistoryModel; renamings --- LeftPanel.qml | 8 +- MiddlePanel.qml | 14 ++++ components/AddressBookTable.qml | 2 +- components/DashboardTable.qml | 2 +- components/HistoryTable.qml | 2 +- get_libwallet_api.sh | 8 +- main.cpp | 13 ++-- main.qml | 7 +- monero-core.pro | 9 ++- pages/History.qml | 2 + pages/Receive.qml | 2 +- pages/Transfer.qml | 2 +- src/libwalletqt/TransactionHistory.cpp | 14 ++-- src/libwalletqt/TransactionHistory.h | 5 +- src/libwalletqt/TransactionInfo.cpp | 12 +-- src/libwalletqt/TransactionInfo.h | 14 +++- src/libwalletqt/Wallet.cpp | 18 ++++- src/libwalletqt/Wallet.h | 13 +++- src/model/TransactionHistoryModel.cpp | 102 +++++++++++++++++++++++++ src/model/TransactionHistoryModel.h | 48 ++++++++++++ wizard/WizardMemoTextInput.qml | 2 +- wizard/WizardRecoveryWallet.qml | 3 +- 22 files changed, 256 insertions(+), 46 deletions(-) create mode 100644 src/model/TransactionHistoryModel.cpp create mode 100644 src/model/TransactionHistoryModel.h diff --git a/LeftPanel.qml b/LeftPanel.qml index 851db047..59793659 100644 --- a/LeftPanel.qml +++ b/LeftPanel.qml @@ -252,17 +252,17 @@ Rectangle { panel.receiveClicked() } } - /* + Rectangle { anchors.left: parent.left anchors.right: parent.right anchors.leftMargin: 16 color: transferButton.checked || historyButton.checked ? "#1C1C1C" : "#505050" height: 1 - }*/ + } // ------------- History tab --------------- - /* + MenuButton { id: historyButton anchors.left: parent.left @@ -276,7 +276,7 @@ Rectangle { panel.historyClicked() } } - + /* Rectangle { anchors.left: parent.left anchors.right: parent.right diff --git a/MiddlePanel.qml b/MiddlePanel.qml index a2cabc1c..2a117081 100644 --- a/MiddlePanel.qml +++ b/MiddlePanel.qml @@ -27,6 +27,8 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import QtQuick 2.2 +import QtQml 2.0 +import QtQuick.Controls 2.0 import QtGraphicalEffects 1.0 Rectangle { @@ -73,6 +75,18 @@ Rectangle { Rectangle { height: 4; width: parent.width / 5; color: "#FF4F41" } } + + + // TODO: replace loader with StackView + +// StackView { +// id: stackView +// anchors.left: parent.left +// anchors.right: parent.right +// anchors.top: styledRow.bottom +// anchors.bottom: parent.bottom +// } + Loader { id: loader anchors.left: parent.left diff --git a/components/AddressBookTable.qml b/components/AddressBookTable.qml index 756445f7..2ad9d2ff 100644 --- a/components/AddressBookTable.qml +++ b/components/AddressBookTable.qml @@ -27,7 +27,7 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import QtQuick 2.0 -import moneroComponents 1.0 +import moneroComponents.Clipboard 1.0 ListView { id: listView diff --git a/components/DashboardTable.qml b/components/DashboardTable.qml index 05b23c6e..1dc0d3b4 100644 --- a/components/DashboardTable.qml +++ b/components/DashboardTable.qml @@ -27,7 +27,7 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import QtQuick 2.0 -import moneroComponents 1.0 +import moneroComponents.Clipboard 1.0 ListView { id: listView diff --git a/components/HistoryTable.qml b/components/HistoryTable.qml index db92aa69..15e3a7d8 100644 --- a/components/HistoryTable.qml +++ b/components/HistoryTable.qml @@ -27,7 +27,7 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import QtQuick 2.0 -import moneroComponents 1.0 +import moneroComponents.Clipboard 1.0 ListView { id: listView diff --git a/get_libwallet_api.sh b/get_libwallet_api.sh index 875ca2e9..0cc850ed 100755 --- a/get_libwallet_api.sh +++ b/get_libwallet_api.sh @@ -1,10 +1,10 @@ #!/bin/bash -MONERO_URL=https://github.com/monero-project/monero.git -MONERO_BRANCH=master -# MONERO_URL=https://github.com/mbg033/monero.git -# MONERO_BRANCH=develop +# MONERO_URL=https://github.com/monero-project/monero.git +# MONERO_BRANCH=master +MONERO_URL=https://github.com/mbg033/monero.git +MONERO_BRANCH=develop # thanks to SO: http://stackoverflow.com/a/20283965/4118915 CPU_CORE_COUNT=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || sysctl -n hw.ncpu) pushd $(pwd) diff --git a/main.cpp b/main.cpp index 129d38c2..d7c510b5 100644 --- a/main.cpp +++ b/main.cpp @@ -39,7 +39,7 @@ #include "Wallet.h" #include "PendingTransaction.h" #include "TranslationManager.h" - +#include "model/TransactionHistoryModel.h" @@ -56,14 +56,15 @@ int main(int argc, char *argv[]) filter *eventFilter = new filter; app.installEventFilter(eventFilter); - qmlRegisterType("moneroComponents", 1, 0, "Clipboard"); + qmlRegisterType("moneroComponents.Clipboard", 1, 0, "Clipboard"); - qmlRegisterUncreatableType("Bitmonero.Wallet", 1, 0, "Wallet", "Wallet can't be instantiated directly"); + qmlRegisterUncreatableType("moneroComponents.Wallet", 1, 0, "Wallet", "Wallet can't be instantiated directly"); - qmlRegisterUncreatableType("Bitmonero.PendingTransaction", 1, 0, "PendingTransaction", + + qmlRegisterUncreatableType("moneroComponents.PendingTransaction", 1, 0, "PendingTransaction", "PendingTransaction can't be instantiated directly"); - qmlRegisterUncreatableType("Bitmonero.WalletManager", 1, 0, "WalletManager", + qmlRegisterUncreatableType("moneroComponents.WalletManager", 1, 0, "WalletManager", "WalletManager can't be instantiated directly"); qmlRegisterUncreatableType("moneroComponents", 1, 0, "TranslationManager", @@ -72,6 +73,8 @@ int main(int argc, char *argv[]) qRegisterMetaType(); + qmlRegisterUncreatableType("moneroComponents", 1, 0, "TransactionHistoryModel", + "TranslationManager can't be instantiated directly"); QQmlApplicationEngine engine; diff --git a/main.qml b/main.qml index d6706d5d..1a97a5d1 100644 --- a/main.qml +++ b/main.qml @@ -32,8 +32,9 @@ import QtQuick.Controls 1.1 import QtQuick.Controls.Styles 1.1 import QtQuick.Dialogs 1.2 import Qt.labs.settings 1.0 -import Bitmonero.Wallet 1.0 -import Bitmonero.PendingTransaction 1.0 + +import moneroComponents.Wallet 1.0 +import moneroComponents.PendingTransaction 1.0 import "components" @@ -146,7 +147,7 @@ ApplicationWindow { } else { var wallet_path = walletPath(); // console.log("opening wallet at: ", wallet_path, "with password: ", appWindow.password); - console.log("opening wallet at: ", wallet_path); + console.log("opening wallet at: ", wallet_path, ", testnet: ", persistentSettings.testnet); walletManager.openWalletAsync(wallet_path, appWindow.password, persistentSettings.testnet); } diff --git a/monero-core.pro b/monero-core.pro index 4c1a5158..6f21e6ea 100644 --- a/monero-core.pro +++ b/monero-core.pro @@ -10,7 +10,8 @@ CONFIG += c++11 QMAKE_DISTCLEAN += -r $$WALLET_ROOT INCLUDEPATH += $$WALLET_ROOT/include \ - $$PWD/src/libwalletqt + $$PWD/src/libwalletqt \ + $$PWD/src HEADERS += \ filter.h \ @@ -22,7 +23,8 @@ HEADERS += \ src/libwalletqt/TransactionHistory.h \ src/libwalletqt/TransactionInfo.h \ oshelper.h \ - TranslationManager.h + TranslationManager.h \ + src/model/TransactionHistoryModel.h SOURCES += main.cpp \ @@ -35,7 +37,8 @@ SOURCES += main.cpp \ src/libwalletqt/TransactionHistory.cpp \ src/libwalletqt/TransactionInfo.cpp \ oshelper.cpp \ - TranslationManager.cpp + TranslationManager.cpp \ + src/model/TransactionHistoryModel.cpp lupdate_only { SOURCES = *.qml \ diff --git a/pages/History.qml b/pages/History.qml index 15161a5d..72046f0d 100644 --- a/pages/History.qml +++ b/pages/History.qml @@ -28,6 +28,8 @@ import QtQuick 2.0 import "../components" +import moneroComponents.Wallet 1.0 +import moneroComponents.WalletManager 1.0 Rectangle { color: "#F0EEEE" diff --git a/pages/Receive.qml b/pages/Receive.qml index e2c1cb7f..208cf25a 100644 --- a/pages/Receive.qml +++ b/pages/Receive.qml @@ -32,7 +32,7 @@ import QtQuick.Controls.Styles 1.4 import QtQuick.Layouts 1.1 import "../components" -import moneroComponents 1.0 +import moneroComponents.Clipboard 1.0 Rectangle { diff --git a/pages/Transfer.qml b/pages/Transfer.qml index 2d011c18..3921b1ef 100644 --- a/pages/Transfer.qml +++ b/pages/Transfer.qml @@ -27,7 +27,7 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import QtQuick 2.0 -import Bitmonero.PendingTransaction 1.0 +import moneroComponents.PendingTransaction 1.0 import "../components" diff --git a/src/libwalletqt/TransactionHistory.cpp b/src/libwalletqt/TransactionHistory.cpp index 2c2c9f73..7466038f 100644 --- a/src/libwalletqt/TransactionHistory.cpp +++ b/src/libwalletqt/TransactionHistory.cpp @@ -3,11 +3,6 @@ #include -int TransactionHistory::count() const -{ - return m_pimpl->count(); -} - TransactionInfo *TransactionHistory::transaction(int index) { // box up Bitmonero::TransactionInfo @@ -39,10 +34,17 @@ QList TransactionHistory::getAll() const void TransactionHistory::refresh() { // XXX this invalidates previously saved history that might be used by clients + emit refreshStarted(); m_pimpl->refresh(); - emit invalidated(); + emit refreshFinished(); } +quint64 TransactionHistory::count() const +{ + return m_pimpl->count(); +} + + TransactionHistory::TransactionHistory(Bitmonero::TransactionHistory *pimpl, QObject *parent) : QObject(parent), m_pimpl(pimpl) { diff --git a/src/libwalletqt/TransactionHistory.h b/src/libwalletqt/TransactionHistory.h index a6287506..560b8df8 100644 --- a/src/libwalletqt/TransactionHistory.h +++ b/src/libwalletqt/TransactionHistory.h @@ -16,14 +16,15 @@ class TransactionHistory : public QObject Q_PROPERTY(int count READ count) public: - int count() const; Q_INVOKABLE TransactionInfo *transaction(int index); Q_INVOKABLE TransactionInfo * transaction(const QString &id); Q_INVOKABLE QList getAll() const; Q_INVOKABLE void refresh(); + quint64 count() const; signals: - void invalidated(); + void refreshStarted(); + void refreshFinished(); public slots: diff --git a/src/libwalletqt/TransactionInfo.cpp b/src/libwalletqt/TransactionInfo.cpp index 192e85e5..40711765 100644 --- a/src/libwalletqt/TransactionInfo.cpp +++ b/src/libwalletqt/TransactionInfo.cpp @@ -1,4 +1,6 @@ #include "TransactionInfo.h" +#include "WalletManager.h" + #include TransactionInfo::Direction TransactionInfo::direction() const @@ -16,15 +18,15 @@ bool TransactionInfo::isFailed() const return m_pimpl->isFailed(); } -quint64 TransactionInfo::amount() const + +QString TransactionInfo::amount() const { - return m_pimpl->amount(); + return WalletManager::instance()->displayAmount(m_pimpl->amount()); } -quint64 TransactionInfo::fee() const +QString TransactionInfo::fee() const { - return m_pimpl->fee(); - + return WalletManager::instance()->displayAmount(m_pimpl->fee()); } quint64 TransactionInfo::blockHeight() const diff --git a/src/libwalletqt/TransactionInfo.h b/src/libwalletqt/TransactionInfo.h index 62c26e2f..4dabc5b4 100644 --- a/src/libwalletqt/TransactionInfo.h +++ b/src/libwalletqt/TransactionInfo.h @@ -10,8 +10,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(quint64 amount READ amount) - Q_PROPERTY(quint64 fee READ fee) + Q_PROPERTY(QString amount READ amount) + Q_PROPERTY(QString fee READ fee) Q_PROPERTY(quint64 blockHeight READ blockHeight) Q_PROPERTY(QString hash READ hash) Q_PROPERTY(QString timestamp READ timestamp) @@ -23,6 +23,8 @@ public: Direction_Out = Bitmonero::TransactionInfo::Direction_Out }; + Q_ENUM(Direction) + // TODO: implement as separate class; // struct Transfer { @@ -30,11 +32,12 @@ public: // const uint64_t amount; // const std::string address; // }; + Direction direction() const; bool isPending() const; bool isFailed() const; - quint64 amount() const; - quint64 fee() const; + QString amount() const; + QString fee() const; quint64 blockHeight() const; //! transaction_id QString hash() const; @@ -51,4 +54,7 @@ private: Bitmonero::TransactionInfo * m_pimpl; }; +// in order to wrap it to QVariant +Q_DECLARE_METATYPE(TransactionInfo*) + #endif // TRANSACTIONINFO_H diff --git a/src/libwalletqt/Wallet.cpp b/src/libwalletqt/Wallet.cpp index 987f4640..4dcf9add 100644 --- a/src/libwalletqt/Wallet.cpp +++ b/src/libwalletqt/Wallet.cpp @@ -1,6 +1,7 @@ #include "Wallet.h" #include "PendingTransaction.h" #include "TransactionHistory.h" +#include "model/TransactionHistoryModel.h" #include "wallet/wallet2_api.h" #include @@ -59,7 +60,10 @@ private: Wallet * m_wallet; }; - +Wallet::Wallet(QObject * parent) + : Wallet(nullptr, parent) +{ +} QString Wallet::getSeed() const { @@ -202,6 +206,16 @@ TransactionHistory *Wallet::history() return m_history; } +TransactionHistoryModel *Wallet::historyModel() +{ + if (!m_historyModel) { + m_historyModel = new TransactionHistoryModel(this); + m_historyModel->setTransactionHistory(this->history()); + } + + return m_historyModel; +} + QString Wallet::generatePaymentId() const { @@ -228,6 +242,7 @@ Wallet::Wallet(Bitmonero::Wallet *w, QObject *parent) : QObject(parent) , m_walletImpl(w) , m_history(nullptr) + , m_historyModel(nullptr) , m_daemonBlockChainHeight(0) , m_daemonBlockChainHeightTtl(DAEMON_BLOCKCHAIN_HEIGHT_CACHE_TTL_SECONDS) { @@ -236,5 +251,6 @@ Wallet::Wallet(Bitmonero::Wallet *w, QObject *parent) Wallet::~Wallet() { + Bitmonero::WalletManagerFactory::getWalletManager()->closeWallet(m_walletImpl); } diff --git a/src/libwalletqt/Wallet.h b/src/libwalletqt/Wallet.h index 703bd186..1a6459d4 100644 --- a/src/libwalletqt/Wallet.h +++ b/src/libwalletqt/Wallet.h @@ -13,6 +13,7 @@ namespace Bitmonero { class TransactionHistory; +class TransactionHistoryModel; class Wallet : public QObject { @@ -27,8 +28,11 @@ 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) public: + + enum Status { Status_Ok = Bitmonero::Wallet::Status_Ok, Status_Error = Bitmonero::Wallet::Status_Error @@ -111,6 +115,9 @@ public: //! returns transaction history TransactionHistory * history(); + //! returns transaction history model + TransactionHistoryModel * historyModel(); + //! generate payment id Q_INVOKABLE QString generatePaymentId() const; @@ -139,9 +146,9 @@ signals: private: + Wallet(QObject * parent = nullptr); Wallet(Bitmonero::Wallet *w, QObject * parent = 0); ~Wallet(); - private: friend class WalletManager; friend class WalletListenerImpl; @@ -149,6 +156,8 @@ private: Bitmonero::Wallet * m_walletImpl; // history lifetime managed by wallet; TransactionHistory * m_history; + // Used for UI history view + TransactionHistoryModel * m_historyModel; QString m_paymentId; mutable QTime m_daemonBlockChainHeightTime; mutable quint64 m_daemonBlockChainHeight; @@ -156,4 +165,6 @@ private: }; + + #endif // WALLET_H diff --git a/src/model/TransactionHistoryModel.cpp b/src/model/TransactionHistoryModel.cpp new file mode 100644 index 00000000..1666981c --- /dev/null +++ b/src/model/TransactionHistoryModel.cpp @@ -0,0 +1,102 @@ +#include "TransactionHistoryModel.h" +#include "TransactionHistory.h" +#include "TransactionInfo.h" + + +TransactionHistoryModel::TransactionHistoryModel(QObject *parent) + : QAbstractListModel(parent), m_transactionHistory(nullptr) +{ + +} + +void TransactionHistoryModel::setTransactionHistory(TransactionHistory *th) +{ + beginResetModel(); + m_transactionHistory = th; + endResetModel(); + emit transactionHistoryChanged(); +} + +TransactionHistory *TransactionHistoryModel::transactionHistory() const +{ + return m_transactionHistory; +} + +QVariant TransactionHistoryModel::data(const QModelIndex &index, int role) const +{ + if (!m_transactionHistory) { + return QVariant(); + } + + if (index.row() < 0 || (unsigned)index.row() >= m_transactionHistory->count()) { + return QVariant(); + } + + TransactionInfo * tInfo = m_transactionHistory->transaction(index.row()); + + + Q_ASSERT(tInfo); + if (!tInfo) { + qCritical("%s: internal error: no transaction info for index %d", __FUNCTION__, index.row()); + return QVariant(); + } + QVariant result; + switch (role) { + case TransactionRole: + result = QVariant::fromValue(tInfo); + break; + case TransactionDirectionRole: + result = QVariant::fromValue(tInfo->direction()); + break; + case TransactionPendingRole: + result = tInfo->isPending(); + break; + case TransactionFailedRole: + result = tInfo->isFailed(); + break; + case TransactionAmountRole: + result = tInfo->amount(); + break; + case TransactionFeeRole: + result = tInfo->fee(); + break; + case TransactionBlockHeightRole: + result = tInfo->blockHeight(); + break; + case TransactionHashRole: + result = tInfo->hash(); + break; + case TransactionTimeStampRole: + result = tInfo->timestamp(); + break; + case TransactionPaymentIdRole: + result = tInfo->paymentId(); + break; + } + + return result; +} + +int TransactionHistoryModel::rowCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent) + return m_transactionHistory ? m_transactionHistory->count() : 0; +} + +QHash TransactionHistoryModel::roleNames() const +{ + QHash roleNames = QAbstractListModel::roleNames(); + roleNames.insert(TransactionRole, "transaction"); + roleNames.insert(TransactionDirectionRole, "direction"); + roleNames.insert(TransactionPendingRole, "isPending"); + roleNames.insert(TransactionFailedRole, "isFailed"); + roleNames.insert(TransactionAmountRole, "amount"); + roleNames.insert(TransactionFeeRole, "fee"); + roleNames.insert(TransactionBlockHeightRole, "blockHeight"); + roleNames.insert(TransactionHashRole, "hash"); + roleNames.insert(TransactionTimeStampRole, "timeStamp"); + roleNames.insert(TransactionPaymentIdRole, "paymentId"); + return roleNames; +} + + diff --git a/src/model/TransactionHistoryModel.h b/src/model/TransactionHistoryModel.h new file mode 100644 index 00000000..2813a89a --- /dev/null +++ b/src/model/TransactionHistoryModel.h @@ -0,0 +1,48 @@ +#ifndef TRANSACTIONHISTORYMODEL_H +#define TRANSACTIONHISTORYMODEL_H + +#include + +class TransactionHistory; +class TransactionInfo; + +/** + * @brief The TransactionHistoryModel class - read-only list model for Transaction History + */ +class TransactionHistoryModel : public QAbstractListModel +{ + Q_OBJECT + Q_PROPERTY(TransactionHistory * transactionHistory READ transactionHistory WRITE setTransactionHistory NOTIFY transactionHistoryChanged) + +public: + enum TransactionInfoRole { + TransactionRole = Qt::UserRole + 1, // for the TransactionInfo object; + TransactionDirectionRole, + TransactionPendingRole, + TransactionFailedRole, + TransactionAmountRole, + TransactionFeeRole, + TransactionBlockHeightRole, + TransactionHashRole, + TransactionTimeStampRole, + TransactionPaymentIdRole + }; + + TransactionHistoryModel(QObject * parent = 0); + void setTransactionHistory(TransactionHistory * th); + TransactionHistory * transactionHistory() const; + + /// QAbstractListModel + virtual QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override; + virtual int rowCount(const QModelIndex & parent = QModelIndex()) const override; + virtual QHash roleNames() const override; + +signals: + void transactionHistoryChanged(); + +private: + TransactionHistory * m_transactionHistory; + +}; + +#endif // TRANSACTIONHISTORYMODEL_H diff --git a/wizard/WizardMemoTextInput.qml b/wizard/WizardMemoTextInput.qml index 9497d9e5..37dbcb39 100644 --- a/wizard/WizardMemoTextInput.qml +++ b/wizard/WizardMemoTextInput.qml @@ -1,5 +1,5 @@ import QtQuick 2.0 -import moneroComponents 1.0 +import moneroComponents.Clipboard 1.0 Column { diff --git a/wizard/WizardRecoveryWallet.qml b/wizard/WizardRecoveryWallet.qml index 505bc239..00cf2440 100644 --- a/wizard/WizardRecoveryWallet.qml +++ b/wizard/WizardRecoveryWallet.qml @@ -27,9 +27,8 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import QtQuick 2.2 -import moneroComponents 1.0 import QtQuick.Dialogs 1.2 -import Bitmonero.Wallet 1.0 +import moneroComponents.Wallet 1.0 import 'utils.js' as Utils Item {