From bd8646dd194771a9ff39bc75530d169a6d570ef6 Mon Sep 17 00:00:00 2001 From: Jacob Brydolf Date: Sat, 1 Oct 2016 03:05:26 +0200 Subject: [PATCH 01/42] UX improvements in wizard - password page styling - tab navigation / focus on load - click language loads next page --- wizard/WizardPassword.qml | 28 +++++++++++++++++----------- wizard/WizardPasswordInput.qml | 24 +++++++++++++++++------- wizard/WizardWelcome.qml | 1 + 3 files changed, 35 insertions(+), 18 deletions(-) diff --git a/wizard/WizardPassword.qml b/wizard/WizardPassword.qml index 8318a785ce..476c5742dd 100644 --- a/wizard/WizardPassword.qml +++ b/wizard/WizardPassword.qml @@ -52,6 +52,8 @@ Item { } else { passwordPage.titleText = qsTr("Now that your wallet has been restored, please set a password for the wallet") + translationManager.emptyString } + + passwordItem.focus = true; } function onPageClosed(settingsObject) { @@ -146,30 +148,34 @@ Item { anchors.topMargin: 24 width: 300 height: 62 + placeholderText : qsTr("Password") + translationManager.emptyString; + KeyNavigation.tab: retypePasswordItem onChanged: handlePassword() - } - - PrivacyLevelSmall { - id: privacyLevel - anchors.left: parent.left - anchors.right: parent.right - anchors.top: passwordItem.bottom - anchors.topMargin: 24 - background: "#F0EEEE" - interactive: false } WizardPasswordInput { id: retypePasswordItem - anchors.top: privacyLevel.bottom + anchors.top: passwordItem.bottom anchors.horizontalCenter: parent.horizontalCenter anchors.topMargin: 24 width: 300 height: 62 + placeholderText : qsTr("Confirm password") + translationManager.emptyString; + KeyNavigation.tab: passwordItem onChanged: handlePassword() } + PrivacyLevelSmall { + id: privacyLevel + anchors.left: parent.left + anchors.right: parent.right + anchors.top: retypePasswordItem.bottom + anchors.topMargin: 60 + background: "#F0EEEE" + interactive: false + } + Component.onCompleted: { console.log } diff --git a/wizard/WizardPasswordInput.qml b/wizard/WizardPasswordInput.qml index 8259742114..00201ecfae 100644 --- a/wizard/WizardPasswordInput.qml +++ b/wizard/WizardPasswordInput.qml @@ -27,24 +27,34 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import QtQuick 2.0 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 -Item { +FocusScope { property alias password: password.text + property alias placeholderText: password.placeholderText signal changed(string password) - TextInput { + TextField { id : password + focus:true anchors.fill: parent - horizontalAlignment: TextInput.AlignHCenter + horizontalAlignment: TextInput.AlignLeft verticalAlignment: TextInput.AlignVCenter font.family: "Arial" font.pixelSize: 32 - renderType: Text.NativeRendering - color: "#35B05A" - passwordCharacter: "•" echoMode: TextInput.Password - focus: true + style: TextFieldStyle { + renderType: Text.NativeRendering + textColor: "#35B05A" + passwordCharacter: "•" + background: Rectangle { + radius: 0 + border.width: 0 + } + } + Keys.onReleased: { changed(text) } diff --git a/wizard/WizardWelcome.qml b/wizard/WizardWelcome.qml index 46448e2c89..ef97f9845c 100644 --- a/wizard/WizardWelcome.qml +++ b/wizard/WizardWelcome.qml @@ -163,6 +163,7 @@ Item { if (data !== null || data !== undefined) { var locale = data.locale translationManager.setLanguage(locale.split("_")[0]); + wizard.switchPage(true) } } } From 0ff3fd32122a22d7c56a289faa6402351f425873 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev Date: Sun, 2 Oct 2016 21:40:40 +0300 Subject: [PATCH 02/42] 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 851db04729..597936598b 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 a2cabc1c48..2a117081e0 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 756445f7d7..2ad9d2ff33 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 05b23c6ee9..1dc0d3b479 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 db92aa6949..15e3a7d8ca 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 875ca2e900..0cc850ed42 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 129d38c21d..d7c510b5a3 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("moneroComponents.Wallet", 1, 0, "Wallet", "Wallet can't be instantiated directly"); - qmlRegisterUncreatableType("Bitmonero.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 d6706d5dfe..1a97a5d1fa 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 4c1a515878..6f21e6eaa9 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 15161a5dda..72046f0d76 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 e2c1cb7f16..208cf25a9a 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 2d011c1846..3921b1ef45 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 2c2c9f7301..7466038f7f 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 a628750652..560b8df806 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 192e85e5fe..40711765d5 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 62c26e2f9f..4dabc5b426 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 @@ class TransactionInfo : public QObject Direction_Out = Bitmonero::TransactionInfo::Direction_Out }; + Q_ENUM(Direction) + // TODO: implement as separate class; // struct Transfer { @@ -30,11 +32,12 @@ class TransactionInfo : public QObject // 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 @@ class TransactionInfo : public QObject 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 987f4640c5..4dcf9add3c 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 @@ class WalletListenerImpl : public Bitmonero::WalletListener 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 703bd186b8..1a6459d4a2 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 @@ class Wallet : public QObject //! returns transaction history TransactionHistory * history(); + //! returns transaction history model + TransactionHistoryModel * historyModel(); + //! generate payment id Q_INVOKABLE QString generatePaymentId() const; @@ -139,9 +146,9 @@ class Wallet : public QObject private: + Wallet(QObject * parent = nullptr); Wallet(Bitmonero::Wallet *w, QObject * parent = 0); ~Wallet(); - private: friend class WalletManager; friend class WalletListenerImpl; @@ -149,6 +156,8 @@ class Wallet : public QObject 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 @@ class Wallet : public QObject }; + + #endif // WALLET_H diff --git a/src/model/TransactionHistoryModel.cpp b/src/model/TransactionHistoryModel.cpp new file mode 100644 index 0000000000..1666981c84 --- /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 0000000000..2813a89ab9 --- /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 9497d9e57f..37dbcb398b 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 505bc23961..00cf2440d7 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 { From 56c3579501f5d9f477b075d56d38baad58b468e6 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev Date: Sun, 2 Oct 2016 23:54:05 +0300 Subject: [PATCH 03/42] Replaced Loader with StackView; Fixed payment id generation --- MiddlePanel.qml | 115 +++++++++++++++++++++++++++------------------- pages/Receive.qml | 9 ++-- 2 files changed, 72 insertions(+), 52 deletions(-) diff --git a/MiddlePanel.qml b/MiddlePanel.qml index 2a117081e0..43fbed4724 100644 --- a/MiddlePanel.qml +++ b/MiddlePanel.qml @@ -30,37 +30,74 @@ import QtQuick 2.2 import QtQml 2.0 import QtQuick.Controls 2.0 import QtGraphicalEffects 1.0 +import "pages" Rectangle { id: root + property Transfer transferView: Transfer { } + property Receive receiveView: Receive { } + property History historyView: History { } + property Item currentView + + onCurrentViewChanged: { + if (currentView) { + stackView.replace(currentView) + } + } + color: "#F0EEEE" signal paymentClicked(string address, string paymentId, double amount, int mixinCount, int priority) signal generatePaymentIdInvoked() - states: [ - State { - name: "Dashboard" - PropertyChanges { target: loader; source: "pages/Dashboard.qml" } - }, State { - name: "History" - PropertyChanges { target: loader; source: "pages/History.qml" } - }, State { - name: "Transfer" - PropertyChanges { target: loader; source: "pages/Transfer.qml" } - }, State { - name: "Receive" - PropertyChanges { target: loader; source: "pages/Receive.qml" } - }, State { - name: "AddressBook" - PropertyChanges { target: loader; source: "pages/AddressBook.qml" } - }, State { - name: "Settings" - PropertyChanges { target: loader; source: "pages/Settings.qml" } - }, State { - name: "Mining" - PropertyChanges { target: loader; source: "pages/Mining.qml" } - } - ] +// states: [ +// State { +// name: "Dashboard" +// PropertyChanges { target: loader; source: "pages/Dashboard.qml" } +// }, State { +// name: "History" +// PropertyChanges { target: loader; source: "pages/History.qml" } +// }, State { +// name: "Transfer" +// PropertyChanges { target: loader; source: "pages/Transfer.qml" } +// }, State { +// name: "Receive" +// PropertyChanges { target: loader; source: "pages/Receive.qml" } +// }, State { +// name: "AddressBook" +// PropertyChanges { target: loader; source: "pages/AddressBook.qml" } +// }, State { +// name: "Settings" +// PropertyChanges { target: loader; source: "pages/Settings.qml" } +// }, State { +// name: "Mining" +// PropertyChanges { target: loader; source: "pages/Mining.qml" } +// } +// ] + + states: [ + State { + name: "Dashboard" + PropertyChanges { } + }, State { + name: "History" + PropertyChanges { target: root; currentView: historyView } + }, State { + name: "Transfer" + PropertyChanges { target: root; currentView: transferView } + }, State { + name: "Receive" + PropertyChanges { target: root; currentView: receiveView } + }, State { + name: "AddressBook" + PropertyChanges { /*TODO*/ } + }, State { + name: "Settings" + PropertyChanges { /*TODO*/ } + }, State { + name: "Mining" + PropertyChanges { /*TODO*/ } + } + ] Row { id: styledRow @@ -75,34 +112,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 - anchors.right: parent.right - anchors.top: styledRow.bottom - anchors.bottom: parent.bottom - onLoaded: { - console.log("Loaded " + item); - } - + StackView { + id: stackView + initialItem: transferView + anchors.fill: parent + anchors.margins: 4 + clip: true // otherwise animation will affect left panel } /* connect "payment" click */ Connections { ignoreUnknownSignals: false - target: loader.item + target: transferView onPaymentClicked : { console.log("MiddlePanel: paymentClicked") paymentClicked(address, paymentId, amount, mixinCount, priority) diff --git a/pages/Receive.qml b/pages/Receive.qml index 208cf25a9a..18486d3431 100644 --- a/pages/Receive.qml +++ b/pages/Receive.qml @@ -43,14 +43,13 @@ Rectangle { function updatePaymentId() { var payment_id = appWindow.persistentSettings.payment_id - if (payment_id.length === 0) { - payment_id = appWindow.wallet.generatePaymentId() + if (typeof appWindow.currentWallet !== 'undefined') { + payment_id = appWindow.currentWallet.generatePaymentId() appWindow.persistentSettings.payment_id = payment_id - appWindow.currentWallet.payment_id = payment_id + addressLine.text = appWindow.currentWallet.address + integratedAddressLine.text = appWindow.currentWallet.integratedAddress(payment_id) } paymentIdLine.text = payment_id - addressLine.text = appWindow.currentWallet.address - integratedAddressLine.text = appWindow.currentWallet.integratedAddress(payment_id) } Clipboard { id: clipboard } From 819be91cb699705f610319735c3cfca7ed3650b5 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev Date: Mon, 3 Oct 2016 00:03:37 +0300 Subject: [PATCH 04/42] Integrating TransactionHistoryModel --- MiddlePanel.qml | 2 ++ pages/History.qml | 7 ++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/MiddlePanel.qml b/MiddlePanel.qml index 43fbed4724..10ed632110 100644 --- a/MiddlePanel.qml +++ b/MiddlePanel.qml @@ -37,6 +37,7 @@ Rectangle { property Transfer transferView: Transfer { } property Receive receiveView: Receive { } property History historyView: History { } + property Item currentView onCurrentViewChanged: { @@ -81,6 +82,7 @@ Rectangle { }, State { name: "History" PropertyChanges { target: root; currentView: historyView } + PropertyChanges { target: historyView; model: appWindow.currentWallet.historyModel } }, State { name: "Transfer" PropertyChanges { target: root; currentView: transferView } diff --git a/pages/History.qml b/pages/History.qml index 72046f0d76..8fce51108e 100644 --- a/pages/History.qml +++ b/pages/History.qml @@ -32,8 +32,13 @@ import moneroComponents.Wallet 1.0 import moneroComponents.WalletManager 1.0 Rectangle { + id: root + property ListModel model: testModel + color: "#F0EEEE" + + Text { id: filterHeaderText anchors.left: parent.left @@ -365,7 +370,7 @@ Rectangle { anchors.leftMargin: 14 anchors.rightMargin: 14 onContentYChanged: flickableScroll.flickableContentYChanged() - model: testModel + model: root.model } } } From 6a5095194054b5023e8fb02e5399fd0f0b10512d Mon Sep 17 00:00:00 2001 From: Ilya Kitaev Date: Mon, 3 Oct 2016 00:16:27 +0300 Subject: [PATCH 05/42] Removed hardcoded height from PasswordDialog --- components/PasswordDialog.qml | 1 - 1 file changed, 1 deletion(-) diff --git a/components/PasswordDialog.qml b/components/PasswordDialog.qml index a8ff294a6e..9edf87fcdf 100644 --- a/components/PasswordDialog.qml +++ b/components/PasswordDialog.qml @@ -40,7 +40,6 @@ Dialog { standardButtons: StandardButton.Ok + StandardButton.Cancel ColumnLayout { id: column - height: 40 anchors.fill: parent Label { From af70c81082bad6fc83fdf3b591fd19a1fc8bdc26 Mon Sep 17 00:00:00 2001 From: Jacob Brydolf Date: Mon, 3 Oct 2016 23:29:30 +0200 Subject: [PATCH 06/42] Added daemon BC sync progress bar depends on https://github.com/monero-project/monero/pull/1173 Signed-off-by: Jacob Brydolf --- LeftPanel.qml | 10 +++- components/DaemonProgress.qml | 90 +++++++++++++++++++++++++++++++++++ main.qml | 5 ++ qml.qrc | 1 + src/libwalletqt/Wallet.cpp | 6 +++ src/libwalletqt/Wallet.h | 5 +- 6 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 components/DaemonProgress.qml diff --git a/LeftPanel.qml b/LeftPanel.qml index 597936598b..93290bc615 100644 --- a/LeftPanel.qml +++ b/LeftPanel.qml @@ -36,6 +36,7 @@ Rectangle { property alias unlockedBalanceText: unlockedBalanceText.text property alias balanceText: balanceText.text property alias networkStatus : networkStatus + property alias daemonProgress : daemonProgress signal dashboardClicked() signal historyClicked() @@ -352,9 +353,16 @@ Rectangle { id: networkStatus anchors.left: parent.left anchors.right: parent.right - anchors.bottom: parent.bottom + anchors.bottom: (daemonProgress.visible)? daemonProgress.top : parent.bottom; connected: false } + + DaemonProgress { + id: daemonProgress + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + } } // indicate disabled state Desaturate { diff --git a/components/DaemonProgress.qml b/components/DaemonProgress.qml new file mode 100644 index 0000000000..1ed533e325 --- /dev/null +++ b/components/DaemonProgress.qml @@ -0,0 +1,90 @@ +// Copyright (c) 2014-2015, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import QtQuick 2.0 + +Item { + id: item + property int fillLevel: 0 + height: 44 + anchors.margins: 10 + visible: false + //clip: true + + function updateProgress(currentBlock,targetBlock){ + if(targetBlock > 0) { + var progressLevel = ((currentBlock/targetBlock) * 100).toFixed(0); + fillLevel = progressLevel + console.log("target block: ",progressLevel) + progressText.text = qsTr("Synchronizing blocks %1/%2").arg(currentBlock.toFixed(0)).arg(targetBlock.toFixed(0)); + console.log("Progress text: " + progressText.text); + + // TODO: lower daemon block height cache, ttl and refresh interval? + + item.visible = (currentBlock < targetBlock) + + } + } + + Rectangle { + id: bar + anchors.left: parent.left + anchors.right: parent.right + anchors.top: parent.top + height: 18 + //radius: 4 + color: "#FFFFFF" + + Rectangle { + id: fillRect + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.margins: 2 + property int maxWidth: parent.width - 4 + width: (maxWidth * fillLevel) / 100 + + color: { + if(item.fillLevel < 99) return "#FF6C3C" + //if(item.fillLevel < 99) return "#FFE00A" + return "#36B25C" + } + + } + } + + Text { + id:progressText + anchors.bottom: parent.bottom + font.family: "Arial" + font.pixelSize: 12 + color: "#545454" + text: qsTr("Synchronizing blocks") + } + +} diff --git a/main.qml b/main.qml index 1a97a5d1fa..82f5c17f18 100644 --- a/main.qml +++ b/main.qml @@ -221,6 +221,9 @@ ApplicationWindow { if (splash.visible) { hideProcessingSplash() } + var dCurrentBlock = currentWallet.daemonBlockChainHeight(); + var dTargetBlock = currentWallet.daemonBlockChainTargetHeight(); + leftPanel.daemonProgress.updateProgress(dCurrentBlock,dTargetBlock); // Store wallet after first refresh. To prevent broken wallet after a crash // TODO: Move this to libwallet? @@ -231,6 +234,7 @@ ApplicationWindow { } leftPanel.networkStatus.connected = currentWallet.connected + onWalletUpdate(); } @@ -247,6 +251,7 @@ ApplicationWindow { } + function walletsFound() { var wallets = walletManager.findWallets(moneroAccountsDir); if (wallets.length === 0) { diff --git a/qml.qrc b/qml.qrc index a44266b95d..ad47ba446d 100644 --- a/qml.qrc +++ b/qml.qrc @@ -116,5 +116,6 @@ lang/flags/italy.png components/PasswordDialog.qml components/ProcessingSplash.qml + components/DaemonProgress.qml diff --git a/src/libwalletqt/Wallet.cpp b/src/libwalletqt/Wallet.cpp index 4dcf9add3c..9f0908b974 100644 --- a/src/libwalletqt/Wallet.cpp +++ b/src/libwalletqt/Wallet.cpp @@ -157,6 +157,12 @@ quint64 Wallet::daemonBlockChainHeight() const return m_daemonBlockChainHeight; } +quint64 Wallet::daemonBlockChainTargetHeight() const +{ + m_daemonBlockChainTargetHeight = m_walletImpl->daemonBlockChainTargetHeight(); + return m_daemonBlockChainTargetHeight; +} + bool Wallet::refresh() { bool result = m_walletImpl->refresh(); diff --git a/src/libwalletqt/Wallet.h b/src/libwalletqt/Wallet.h index 1a6459d4a2..d3ca40856d 100644 --- a/src/libwalletqt/Wallet.h +++ b/src/libwalletqt/Wallet.h @@ -92,6 +92,9 @@ class Wallet : public QObject //! returns daemon's blockchain height Q_INVOKABLE quint64 daemonBlockChainHeight() const; + //! returns daemon's blockchain target height + Q_INVOKABLE quint64 daemonBlockChainTargetHeight() const; + //! refreshes the wallet Q_INVOKABLE bool refresh(); @@ -162,7 +165,7 @@ class Wallet : public QObject mutable QTime m_daemonBlockChainHeightTime; mutable quint64 m_daemonBlockChainHeight; int m_daemonBlockChainHeightTtl; - + mutable quint64 m_daemonBlockChainTargetHeight; }; From cd1247c2923b954512eb90aaaadc0e2e41be9cbc Mon Sep 17 00:00:00 2001 From: Jacob Brydolf Date: Mon, 3 Oct 2016 23:52:48 +0200 Subject: [PATCH 07/42] Added option to show seed on settings-page Signed-off-by: Jacob Brydolf --- LeftPanel.qml | 4 +- MiddlePanel.qml | 3 +- pages/Settings.qml | 103 ++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 105 insertions(+), 5 deletions(-) diff --git a/LeftPanel.qml b/LeftPanel.qml index 93290bc615..7209a6dcf2 100644 --- a/LeftPanel.qml +++ b/LeftPanel.qml @@ -331,7 +331,7 @@ Rectangle { color: miningButton.checked || settingsButton.checked ? "#1C1C1C" : "#505050" height: 1 } - + */ // ------------- Settings tab --------------- MenuButton { id: settingsButton @@ -346,7 +346,7 @@ Rectangle { panel.settingsClicked() } } - */ + } NetworkStatusItem { diff --git a/MiddlePanel.qml b/MiddlePanel.qml index 10ed632110..a8529c9b26 100644 --- a/MiddlePanel.qml +++ b/MiddlePanel.qml @@ -37,6 +37,7 @@ Rectangle { property Transfer transferView: Transfer { } property Receive receiveView: Receive { } property History historyView: History { } + property Settings settingsView: Settings { } property Item currentView @@ -94,7 +95,7 @@ Rectangle { PropertyChanges { /*TODO*/ } }, State { name: "Settings" - PropertyChanges { /*TODO*/ } + PropertyChanges { target: root; currentView: settingsView } }, State { name: "Mining" PropertyChanges { /*TODO*/ } diff --git a/pages/Settings.qml b/pages/Settings.qml index e9a5047602..a53ea77f80 100644 --- a/pages/Settings.qml +++ b/pages/Settings.qml @@ -27,8 +27,107 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import QtQuick 2.0 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 +import QtQuick.Layouts 1.1 + +import "../components" +import moneroComponents 1.0 +import moneroComponents.Clipboard 1.0 Rectangle { - width: 100 - height: 62 + + color: "#F0EEEE" + + Clipboard { id: clipboard } + + + ColumnLayout { + id: mainLayout + anchors.margins: 40 + anchors.left: parent.left + anchors.top: parent.top + anchors.right: parent.right + + spacing: 20 + property int labelWidth: 120 + property int editWidth: 400 + property int lineEditFontSize: 12 + + RowLayout { + id: paymentIdRow + Label { + id: seedLabel + color: "#4A4949" + text: qsTr("Mnemonic seed") + translationManager.emptyString + } + + TextArea { + id: memoTextInput + textMargin: 8 + font.family: "Arial" + font.pointSize: 15 + wrapMode: TextEdit.WordWrap + readOnly: true + selectByMouse: true + height: 300 + width: 500 + text: qsTr("Click button to show seed") + translationManager.emptyString + } + Image { + id : clipboardButton + anchors.right: memoTextInput.right + anchors.bottom: memoTextInput.bottom + source: "qrc:///images/greyTriangle.png" + Image { + anchors.centerIn: parent + source: "qrc:///images/copyToClipboard.png" + } + MouseArea { + anchors.fill: parent + cursorShape: Qt.PointingHandCursor + onClicked: clipboard.setText(memoTextInput.text) + } + } + + + StandardButton { + id: showSeedbtn + width: 80 + fontSize: 14 + shadowReleasedColor: "#FF4304" + shadowPressedColor: "#B32D00" + releasedColor: "#FF6C3C" + pressedColor: "#FF4304" + text: qsTr("Show seed") + onClicked: { + memoTextInput.text = currentWallet.seed + } + } + } + + RowLayout { + id: wordsTipTextRow + + Text { + id: wordsTipText + font.family: "Arial" + font.pixelSize: 15 + color: "#4A4646" + wrapMode: Text.WordWrap + text: qsTr("It is very important to write it down as this is the only backup you will need for your wallet.") + + translationManager.emptyString + } + } + + + Component.onCompleted: { + console.log("Settings page loaded"); + } + + } } + + + + From 5814c19962e713782ebf9c0dcb218058f697ab36 Mon Sep 17 00:00:00 2001 From: Jacob Brydolf Date: Mon, 3 Oct 2016 00:46:06 +0200 Subject: [PATCH 08/42] Fixed overlapping clipboard icons on recieve page --- components/LineEdit.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/LineEdit.qml b/components/LineEdit.qml index 817868819c..296c0c9890 100644 --- a/components/LineEdit.qml +++ b/components/LineEdit.qml @@ -56,7 +56,7 @@ Item { id: input anchors.fill: parent anchors.leftMargin: 4 - anchors.rightMargin: 4 + anchors.rightMargin: 30 font.pixelSize: parent.fontSize } } From 53d3bc4f06eb8f4437b08c48ffff08d4ae793eac Mon Sep 17 00:00:00 2001 From: Ilya Kitaev Date: Tue, 4 Oct 2016 02:14:09 +0300 Subject: [PATCH 09/42] Receive page: display long address from the beginning in TextField --- components/LineEdit.qml | 1 + pages/Receive.qml | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/components/LineEdit.qml b/components/LineEdit.qml index 296c0c9890..2ebc6e0c84 100644 --- a/components/LineEdit.qml +++ b/components/LineEdit.qml @@ -33,6 +33,7 @@ Item { property alias text: input.text property alias validator: input.validator property alias readOnly : input.readOnly + property alias cursorPosition: input.cursorPosition property int fontSize: 18 diff --git a/pages/Receive.qml b/pages/Receive.qml index 18486d3431..1345af993e 100644 --- a/pages/Receive.qml +++ b/pages/Receive.qml @@ -86,6 +86,8 @@ Rectangle { readOnly: true width: mainLayout.editWidth Layout.fillWidth: true + onTextChanged: cursorPosition = 0 + IconButton { imageSource: "../images/copyToClipboard.png" onClicked: { @@ -115,6 +117,9 @@ Rectangle { readOnly: true width: mainLayout.editWidth Layout.fillWidth: true + + onTextChanged: cursorPosition = 0 + IconButton { imageSource: "../images/copyToClipboard.png" onClicked: { From 9cc92bf9d69652104b28e0907de12d83cfadaa20 Mon Sep 17 00:00:00 2001 From: Jacob Brydolf Date: Tue, 4 Oct 2016 12:15:29 +0200 Subject: [PATCH 10/42] added onPageCompleted --- MiddlePanel.qml | 5 +++++ pages/Receive.qml | 21 +++++++++++++-------- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/MiddlePanel.qml b/MiddlePanel.qml index a8529c9b26..6ce1c2424d 100644 --- a/MiddlePanel.qml +++ b/MiddlePanel.qml @@ -44,6 +44,11 @@ Rectangle { onCurrentViewChanged: { if (currentView) { stackView.replace(currentView) + + // Component.onCompleted is called before wallet is initilized + if (typeof currentView.onPageCompleted === "function") { + currentView.onPageCompleted(); + } } } diff --git a/pages/Receive.qml b/pages/Receive.qml index 1345af993e..4ea32a2f32 100644 --- a/pages/Receive.qml +++ b/pages/Receive.qml @@ -1,21 +1,21 @@ // Copyright (c) 2014-2015, The Monero Project -// +// // All rights reserved. -// +// // Redistribution and use in source and binary forms, with or without modification, are // permitted provided that the following conditions are met: -// +// // 1. Redistributions of source code must retain the above copyright notice, this list of // conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright notice, this list // of conditions and the following disclaimer in the documentation and/or other // materials provided with the distribution. -// +// // 3. Neither the name of the copyright holder nor the names of its contributors may be // used to endorse or promote products derived from this software without specific // prior written permission. -// +// // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL @@ -49,6 +49,7 @@ Rectangle { addressLine.text = appWindow.currentWallet.address integratedAddressLine.text = appWindow.currentWallet.integratedAddress(payment_id) } + paymentIdLine.text = payment_id } @@ -180,9 +181,13 @@ Rectangle { } - Component.onCompleted: { + function onPageCompleted() { console.log("Receive page loaded"); - updatePaymentId() + + if(addressLine.text.length == 0) { + updatePaymentId() + } + } } From 522b0671adf946bb4def414f1bbdbca492cf0cd6 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev Date: Tue, 4 Oct 2016 23:12:58 +0300 Subject: [PATCH 11/42] Simple transaction history --- components/HistoryTable.qml | 53 ++++++++++++++++---------- main.cpp | 3 ++ pages/History.qml | 5 ++- src/libwalletqt/TransactionHistory.cpp | 8 ++++ src/libwalletqt/TransactionInfo.cpp | 16 ++++++-- src/libwalletqt/TransactionInfo.h | 15 ++++++-- src/libwalletqt/Wallet.cpp | 13 +++++-- src/model/TransactionHistoryModel.cpp | 20 ++++++++++ src/model/TransactionHistoryModel.h | 13 +++++-- 9 files changed, 110 insertions(+), 36 deletions(-) diff --git a/components/HistoryTable.qml b/components/HistoryTable.qml index 15e3a7d8ca..13bf377580 100644 --- a/components/HistoryTable.qml +++ b/components/HistoryTable.qml @@ -29,10 +29,12 @@ import QtQuick 2.0 import moneroComponents.Clipboard 1.0 + ListView { id: listView clip: true boundsBehavior: ListView.StopAtBounds + property var previousItem footer: Rectangle { height: 127 @@ -48,7 +50,7 @@ ListView { } } - property var previousItem + delegate: Rectangle { id: delegate height: 114 @@ -63,13 +65,13 @@ ListView { anchors.right: parent.right anchors.top: parent.top anchors.topMargin: 14 - + // -- direction indicator Rectangle { id: dot width: 14 height: width radius: width / 2 - color: out ? "#FF4F41" : "#36B05B" + color: isOut ? "#FF4F41" : "#36B05B" } Item { //separator @@ -77,6 +79,7 @@ ListView { height: 14 } + // -- description aka recepient name from address book (TODO) Text { id: descriptionText width: text.length ? (descriptionArea.containsMouse ? parent.width - x - 12 : 120) : 0 @@ -100,7 +103,7 @@ ListView { height: 14 visible: !descriptionArea.containsMouse } - + // -- address (in case outgoing transaction) - N/A in case of incoming Text { id: addressText anchors.verticalCenter: dot.verticalCenter @@ -109,11 +112,11 @@ ListView { font.family: "Arial" font.pixelSize: 14 color: "#545454" - text: address + text: hash visible: !descriptionArea.containsMouse } } - + // -- "PaymentID" title Text { id: paymentLabel anchors.left: parent.left @@ -128,7 +131,7 @@ ListView { color: "#535353" text: paymentId !== "" ? qsTr("Payment ID:") + translationManager.emptyString : "" } - + // -- "PaymentID" value Text { anchors.bottom: paymentLabel.bottom anchors.left: paymentLabel.right @@ -143,7 +146,7 @@ ListView { color: "#545454" text: paymentId } - + // -- "Date", "Balance" and "Amound" section Row { anchors.left: parent.left anchors.bottom: parent.bottom @@ -155,6 +158,7 @@ ListView { height: 14 } + // -- "Date" column Column { anchors.top: parent.top width: 215 @@ -189,10 +193,13 @@ ListView { } } } - + // -- "Balance" column + // XXX: we don't have a balance + /* Column { anchors.top: parent.top width: 148 + visible: false Text { anchors.left: parent.left @@ -210,7 +217,9 @@ ListView { text: balance } } + */ + // -- "Amount column Column { anchors.top: parent.top width: 148 @@ -230,8 +239,8 @@ ListView { anchors.bottomMargin: 3 font.family: "Arial" font.pixelSize: 16 - color: out ? "#FF4F41" : "#36B05B" - text: out ? "↓" : "↑" + color: isOut ? "#FF4F41" : "#36B05B" + text: isOut ? "↓" : "↑" } Text { @@ -239,22 +248,16 @@ ListView { font.family: "Arial" font.pixelSize: 18 font.letterSpacing: -1 - color: out ? "#FF4F41" : "#36B05B" + color: isOut ? "#FF4F41" : "#36B05B" text: amount } } } } - ListModel { - id: dropModel - ListElement { name: "Copy address to clipboard"; icon: "../images/dropdownCopy.png" } - ListElement { name: "Add to address book"; icon: "../images/dropdownAdd.png" } - ListElement { name: "Send to same destination"; icon: "../images/dropdownSend.png" } - ListElement { name: "Find similar transactions"; icon: "../images/dropdownSearch.png" } - } - Clipboard { id: clipboard } + + TableDropdown { id: dropdown anchors.right: parent.right @@ -283,4 +286,14 @@ ListView { color: "#DBDBDB" } } + + ListModel { + id: dropModel + ListElement { name: "Copy address to clipboard"; icon: "../images/dropdownCopy.png" } + ListElement { name: "Add to address book"; icon: "../images/dropdownAdd.png" } + ListElement { name: "Send to same destination"; icon: "../images/dropdownSend.png" } + ListElement { name: "Find similar transactions"; icon: "../images/dropdownSearch.png" } + } + + Clipboard { id: clipboard } } diff --git a/main.cpp b/main.cpp index d7c510b5a3..1709dc886a 100644 --- a/main.cpp +++ b/main.cpp @@ -39,6 +39,7 @@ #include "Wallet.h" #include "PendingTransaction.h" #include "TranslationManager.h" +#include "TransactionInfo.h" #include "model/TransactionHistoryModel.h" @@ -72,6 +73,8 @@ int main(int argc, char *argv[]) qRegisterMetaType(); + qRegisterMetaType(); + qmlRegisterUncreatableType("moneroComponents", 1, 0, "TransactionHistoryModel", "TranslationManager can't be instantiated directly"); diff --git a/pages/History.qml b/pages/History.qml index 8fce51108e..15cf1bc07d 100644 --- a/pages/History.qml +++ b/pages/History.qml @@ -33,10 +33,13 @@ import moneroComponents.WalletManager 1.0 Rectangle { id: root - property ListModel model: testModel + property var model: testModel color: "#F0EEEE" + onModelChanged: { + console.log("model.rowCount: " + model.rowCount()) + } Text { diff --git a/src/libwalletqt/TransactionHistory.cpp b/src/libwalletqt/TransactionHistory.cpp index 7466038f7f..8f52f07e10 100644 --- a/src/libwalletqt/TransactionHistory.cpp +++ b/src/libwalletqt/TransactionHistory.cpp @@ -2,11 +2,18 @@ #include "TransactionInfo.h" #include +#include + TransactionInfo *TransactionHistory::transaction(int index) { // box up Bitmonero::TransactionInfo Bitmonero::TransactionInfo * impl = m_pimpl->transaction(index); + if (!impl) { + qCritical("%s: no transaction info for index %d", __FUNCTION__, index); + qCritical("%s: there's %d transactions in backend", __FUNCTION__, m_pimpl->count()); + return nullptr; + } TransactionInfo * result = new TransactionInfo(impl, this); return result; } @@ -34,6 +41,7 @@ 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 refreshFinished(); diff --git a/src/libwalletqt/TransactionInfo.cpp b/src/libwalletqt/TransactionInfo.cpp index 40711765d5..3aa7334cb1 100644 --- a/src/libwalletqt/TransactionInfo.cpp +++ b/src/libwalletqt/TransactionInfo.cpp @@ -39,13 +39,23 @@ QString TransactionInfo::hash() const return QString::fromStdString(m_pimpl->hash()); } -QString TransactionInfo::timestamp() +QDateTime TransactionInfo::timestamp() const { - QString result = QDateTime::fromTime_t(m_pimpl->timestamp()).toString(Qt::ISODate); + QDateTime result = QDateTime::fromTime_t(m_pimpl->timestamp()); return result; } -QString TransactionInfo::paymentId() +QString TransactionInfo::date() const +{ + return timestamp().date().toString(Qt::ISODate); +} + +QString TransactionInfo::time() const +{ + return timestamp().time().toString(Qt::ISODate); +} + +QString TransactionInfo::paymentId() const { return QString::fromStdString(m_pimpl->paymentId()); } diff --git a/src/libwalletqt/TransactionInfo.h b/src/libwalletqt/TransactionInfo.h index 4dabc5b426..3381131ad8 100644 --- a/src/libwalletqt/TransactionInfo.h +++ b/src/libwalletqt/TransactionInfo.h @@ -1,8 +1,9 @@ #ifndef TRANSACTIONINFO_H #define TRANSACTIONINFO_H -#include #include +#include +#include class TransactionInfo : public QObject { @@ -14,7 +15,9 @@ class TransactionInfo : public QObject Q_PROPERTY(QString fee READ fee) Q_PROPERTY(quint64 blockHeight READ blockHeight) Q_PROPERTY(QString hash READ hash) - Q_PROPERTY(QString timestamp READ timestamp) + Q_PROPERTY(QDateTime timestamp READ timestamp) + Q_PROPERTY(QString date READ date) + Q_PROPERTY(QString time READ time) Q_PROPERTY(QString paymentId READ paymentId) public: @@ -41,8 +44,11 @@ class TransactionInfo : public QObject quint64 blockHeight() const; //! transaction_id QString hash() const; - QString timestamp(); - QString paymentId(); + QDateTime timestamp() const; + QString date() const; + QString time() const; + QString paymentId() const; + // TODO: implement it //! only applicable for output transactions @@ -57,4 +63,5 @@ class TransactionInfo : public QObject // 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 9f0908b974..39d40a17bf 100644 --- a/src/libwalletqt/Wallet.cpp +++ b/src/libwalletqt/Wallet.cpp @@ -40,12 +40,14 @@ class WalletListenerImpl : public Bitmonero::WalletListener virtual void newBlock(uint64_t height) { // qDebug() << __FUNCTION__; + m_wallet->m_history->refresh(); emit m_wallet->newBlock(height); } virtual void updated() { qDebug() << __FUNCTION__; + m_wallet->m_history->refresh(); emit m_wallet->updated(); } @@ -53,6 +55,7 @@ class WalletListenerImpl : public Bitmonero::WalletListener virtual void refreshed() { qDebug() << __FUNCTION__; + emit m_wallet->refreshed(); } @@ -166,6 +169,7 @@ quint64 Wallet::daemonBlockChainTargetHeight() const bool Wallet::refresh() { bool result = m_walletImpl->refresh(); + m_history->refresh(); if (result) emit updated(); return result; @@ -205,10 +209,10 @@ void Wallet::disposeTransaction(PendingTransaction *t) TransactionHistory *Wallet::history() { - if (!m_history) { - Bitmonero::TransactionHistory * impl = m_walletImpl->history(); - m_history = new TransactionHistory(impl, this); - } +// if (m_history->count() == 0) { +// m_history->refresh(); +// } + return m_history; } @@ -252,6 +256,7 @@ Wallet::Wallet(Bitmonero::Wallet *w, QObject *parent) , m_daemonBlockChainHeight(0) , m_daemonBlockChainHeightTtl(DAEMON_BLOCKCHAIN_HEIGHT_CACHE_TTL_SECONDS) { + m_history = new TransactionHistory(m_walletImpl->history(), this); m_walletImpl->setListener(new WalletListenerImpl(this)); } diff --git a/src/model/TransactionHistoryModel.cpp b/src/model/TransactionHistoryModel.cpp index 1666981c84..b8f23f68af 100644 --- a/src/model/TransactionHistoryModel.cpp +++ b/src/model/TransactionHistoryModel.cpp @@ -2,6 +2,8 @@ #include "TransactionHistory.h" #include "TransactionInfo.h" +#include + TransactionHistoryModel::TransactionHistoryModel(QObject *parent) : QAbstractListModel(parent), m_transactionHistory(nullptr) @@ -14,6 +16,12 @@ void TransactionHistoryModel::setTransactionHistory(TransactionHistory *th) beginResetModel(); m_transactionHistory = th; endResetModel(); + + connect(m_transactionHistory, &TransactionHistory::refreshStarted, + this, &TransactionHistoryModel::beginResetModel); + connect(m_transactionHistory, &TransactionHistory::refreshFinished, + this, &TransactionHistoryModel::endResetModel); + emit transactionHistoryChanged(); } @@ -72,6 +80,15 @@ QVariant TransactionHistoryModel::data(const QModelIndex &index, int role) const case TransactionPaymentIdRole: result = tInfo->paymentId(); break; + case TransactionIsOutRole: + result = tInfo->direction() == TransactionInfo::Direction_Out; + break; + case TransactionDateRole: + result = tInfo->date(); + break; + case TransactionTimeRole: + result = tInfo->time(); + break; } return result; @@ -96,6 +113,9 @@ QHash TransactionHistoryModel::roleNames() const roleNames.insert(TransactionHashRole, "hash"); roleNames.insert(TransactionTimeStampRole, "timeStamp"); roleNames.insert(TransactionPaymentIdRole, "paymentId"); + roleNames.insert(TransactionIsOutRole, "isOut"); + roleNames.insert(TransactionDateRole, "date"); + roleNames.insert(TransactionTimeRole, "time"); return roleNames; } diff --git a/src/model/TransactionHistoryModel.h b/src/model/TransactionHistoryModel.h index 2813a89ab9..96d3ff329e 100644 --- a/src/model/TransactionHistoryModel.h +++ b/src/model/TransactionHistoryModel.h @@ -25,7 +25,12 @@ class TransactionHistoryModel : public QAbstractListModel TransactionBlockHeightRole, TransactionHashRole, TransactionTimeStampRole, - TransactionPaymentIdRole + TransactionPaymentIdRole, + // extra role (alias) for TransactionDirectionRole (as UI currently wants just boolean "out") + TransactionIsOutRole, + // extra roles for date and time (as UI wants date and time separately) + TransactionDateRole, + TransactionTimeRole }; TransactionHistoryModel(QObject * parent = 0); @@ -33,9 +38,9 @@ class TransactionHistoryModel : public QAbstractListModel 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; + 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(); From 9700944b7f67dc3f0d6b9de4994250f27dfe5066 Mon Sep 17 00:00:00 2001 From: Jacob Brydolf Date: Wed, 5 Oct 2016 00:18:50 +0200 Subject: [PATCH 12/42] close wallet before reopen --- main.qml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/main.qml b/main.qml index 82f5c17f18..d6d454099c 100644 --- a/main.qml +++ b/main.qml @@ -139,11 +139,19 @@ ApplicationWindow { middlePanel.paymentClicked.connect(handlePayment); // basicPanel.paymentClicked.connect(handlePayment); + // currentWallet is defined on daemon address change - close/reopen + if (currentWallet !== undefined) { + console.log("closing currentWallet") + walletManager.closeWallet(currentWallet); + } // wallet already opened with wizard, we just need to initialize it if (typeof wizard.settings['wallet'] !== 'undefined') { + console.log("using wizard wallet") connectWallet(wizard.settings['wallet']) isNewWallet = true + // We don't need the wizard wallet any more - delete to avoid conflict with daemon adress change + delete wizard.settings['wallet'] } else { var wallet_path = walletPath(); // console.log("opening wallet at: ", wallet_path, "with password: ", appWindow.password); From 2966b0db698eabfff79a461c20f2f37f53ba3666 Mon Sep 17 00:00:00 2001 From: Jacob Brydolf Date: Wed, 5 Oct 2016 00:21:59 +0200 Subject: [PATCH 13/42] settings page: daemon change + password prompt on seed view --- pages/Settings.qml | 134 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 129 insertions(+), 5 deletions(-) diff --git a/pages/Settings.qml b/pages/Settings.qml index a53ea77f80..699ec672ac 100644 --- a/pages/Settings.qml +++ b/pages/Settings.qml @@ -30,6 +30,8 @@ import QtQuick 2.0 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 import QtQuick.Layouts 1.1 +import QtQuick.Dialogs 1.2 + import "../components" import moneroComponents 1.0 @@ -37,10 +39,33 @@ import moneroComponents.Clipboard 1.0 Rectangle { + property var daemonAddress + color: "#F0EEEE" Clipboard { id: clipboard } + function initSettings(){ + + + // Mnemonic seed settings + memoTextInput.text = qsTr("Click button to show seed") + translationManager.emptyString + showSeedbtn.visible = true + + // Daemon settings + daemonAddress = persistentSettings.daemon_address.split(":"); + console.log("address" + persistentSettings.daemon_address) + // try connecting to daemon + var connectedToDaemon = currentWallet.connectToDaemon(); + + if(!connectedToDaemon){ + console.log("not connected"); + //TODO: Print error? + //daemonStatusText.text = qsTr("Unable to connect to Daemon.") + //daemonStatusText.visible = true + } + + } ColumnLayout { id: mainLayout @@ -72,7 +97,6 @@ Rectangle { selectByMouse: true height: 300 width: 500 - text: qsTr("Click button to show seed") + translationManager.emptyString } Image { id : clipboardButton @@ -101,9 +125,28 @@ Rectangle { pressedColor: "#FF4304" text: qsTr("Show seed") onClicked: { - memoTextInput.text = currentWallet.seed + settingsPasswordDialog.open(); + } + } + + PasswordDialog { + id: settingsPasswordDialog + standardButtons: StandardButton.Ok + StandardButton.Cancel + onAccepted: { + if(appWindow.password == settingsPasswordDialog.password){ + memoTextInput.text = currentWallet.seed + showSeedbtn.visible = false + } + + } + onRejected: { + + } + onDiscard: { + } } + } RowLayout { @@ -121,11 +164,92 @@ Rectangle { } - Component.onCompleted: { - console.log("Settings page loaded"); - } + RowLayout { + id: daemonAddrRow + Label { + id: daemonAddrLabel + color: "#4A4949" + text: qsTr("Daemon adress") + translationManager.emptyString + } + + + LineEdit { + id: daemonAddr + width: 180 + text: (daemonAddress != undefined)? daemonAddress[0] : "" + placeholderText: qsTr("Hostname / IP") + } + LineEdit { + id: daemonPort + width: 150 + text: (daemonAddress != undefined)? daemonAddress[1] : "" + placeholderText: qsTr("Port") + } + + + StandardButton { + id: daemonAddrSave + anchors.left: daemonPort.right + anchors.leftMargin: 30 + width: 60 + text: qsTr("Save") + translationManager.emptyString + shadowReleasedColor: "#FF4304" + shadowPressedColor: "#B32D00" + releasedColor: "#FF6C3C" + pressedColor: "#FF4304" + visible: true + onClicked: { + console.log("saving daemon adress settings") + var newDaemon = daemonAddr.text + ":" + daemonPort.text + if(persistentSettings.daemon_address != newDaemon) { + persistentSettings.daemon_address = newDaemon + //reconnect wallet + appWindow.initialize(); + } + } + } + + } + + RowLayout { + id: daemonStatusRow + Text { + id: daemonStatusText + font.family: "Arial" + font.pixelSize: 18 + wrapMode: Text.Wrap + textFormat: Text.RichText + horizontalAlignment: Text.AlignHCenter + color: "#FF0000" + visible: true //!currentWallet.connected + } + +// StandardButton { +// id: checkConnectionButton +// anchors.left: daemonStatusText.right +// anchors.leftMargin: 30 +// width: 90 +// text: qsTr("Check again") + translationManager.emptyString +// shadowReleasedColor: "#FF4304" +// shadowPressedColor: "#B32D00" +// releasedColor: "#FF6C3C" +// pressedColor: "#FF4304" +// visible: true +// onClicked: { +// checkDaemonConnection(); +// } +// } + } } + + + + function onPageCompleted() { + console.log("Settings page loaded"); + initSettings(); + } + } From defc2a414abe6df837682d1472db0272f0b55eca Mon Sep 17 00:00:00 2001 From: Ilya Kitaev Date: Fri, 7 Oct 2016 00:46:42 +0300 Subject: [PATCH 14/42] build: get_libwallet_api.sh accepts build type ("Debug" or "Release", release is default); extra build script that skips cmake invocations --- build_libwallet_api.sh | 52 ++++++++++++++++++++++++++++++++++++++++++ get_libwallet_api.sh | 13 +++++++---- 2 files changed, 61 insertions(+), 4 deletions(-) create mode 100755 build_libwallet_api.sh diff --git a/build_libwallet_api.sh b/build_libwallet_api.sh new file mode 100755 index 0000000000..832b48d267 --- /dev/null +++ b/build_libwallet_api.sh @@ -0,0 +1,52 @@ +#!/bin/bash + + +# MONERO_URL=https://github.com/monero-project/monero.git +# MONERO_BRANCH=master +CPU_CORE_COUNT=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || sysctl -n hw.ncpu) +pushd $(pwd) +ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +source $ROOT_DIR/utils.sh + + +INSTALL_DIR=$ROOT_DIR/wallet +MONERO_DIR=$ROOT_DIR/monero + + +mkdir -p $MONERO_DIR/build/release +pushd $MONERO_DIR/build/release + +# reusing function from "utils.sh" +platform=$(get_platform) + +pushd $MONERO_DIR/build/release/src/wallet +make -j$CPU_CORE_COUNT +make install -j$CPU_CORE_COUNT +popd + +# unbound is one more dependency. can't be merged to the wallet_merged +# since filename conflict (random.c.obj) +# for Linux, we use libunbound shipped with the system, so we don't need to build it + +if [ "$platform" != "linux" ]; then + echo "Building libunbound..." + pushd $MONERO_DIR/build/release/external/unbound + # no need to make, it was already built as dependency for libwallet + # make -j$CPU_CORE_COUNT + make install -j$CPU_CORE_COUNT + popd +fi + +popd + + + + + + + + + + + diff --git a/get_libwallet_api.sh b/get_libwallet_api.sh index 0cc850ed42..d46b9910ae 100755 --- a/get_libwallet_api.sh +++ b/get_libwallet_api.sh @@ -5,6 +5,11 @@ # MONERO_BRANCH=master MONERO_URL=https://github.com/mbg033/monero.git MONERO_BRANCH=develop +# Buidling "debug" build optionally +BUILD_TYPE=$1 +if [ -z $BUILD_TYPE ]; then + BUILD_TYPE=Release +fi # 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) @@ -39,19 +44,19 @@ platform=$(get_platform) if [ "$platform" == "darwin" ]; then # Do something under Mac OS X platform echo "Configuring build for MacOS.." - cmake -D CMAKE_BUILD_TYPE=Release -D STATIC=ON -D BUILD_GUI_DEPS=ON -D INSTALL_VENDORED_LIBUNBOUND=ON -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../.. + cmake -D CMAKE_BUILD_TYPE=$BUILD_TYPE -D STATIC=ON -D BUILD_GUI_DEPS=ON -D INSTALL_VENDORED_LIBUNBOUND=ON -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../.. elif [ "$platform" == "linux" ]; then # Do something under GNU/Linux platform echo "Configuring build for Linux.." - cmake -D CMAKE_BUILD_TYPE=Release -D STATIC=ON -D BUILD_GUI_DEPS=ON -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../.. + cmake -D CMAKE_BUILD_TYPE=$BUILD_TYPE -D STATIC=ON -D BUILD_GUI_DEPS=ON -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" ../.. elif [ "$platform" == "mingw64" ]; then # Do something under Windows NT platform echo "Configuring build for MINGW64.." - cmake -D CMAKE_BUILD_TYPE=Release -D STATIC=ON -D BUILD_GUI_DEPS=ON -D INSTALL_VENDORED_LIBUNBOUND=ON -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" -G "MSYS Makefiles" ../.. + cmake -D CMAKE_BUILD_TYPE=$BUILD_TYPE -D STATIC=ON -D BUILD_GUI_DEPS=ON -D INSTALL_VENDORED_LIBUNBOUND=ON -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" -G "MSYS Makefiles" ../.. elif [ "$platform" == "mingw32" ]; then # Do something under Windows NT platform echo "Configuring build for MINGW32.." - cmake -D CMAKE_BUILD_TYPE=Release -D STATIC=ON -D BUILD_GUI_DEPS=ON -D INSTALL_VENDORED_LIBUNBOUND=ON -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" -G "MSYS Makefiles" ../.. + cmake -D CMAKE_BUILD_TYPE=$BUILD_TYPE -D STATIC=ON -D BUILD_GUI_DEPS=ON -D INSTALL_VENDORED_LIBUNBOUND=ON -D CMAKE_INSTALL_PREFIX="$MONERO_DIR" -G "MSYS Makefiles" ../.. else echo "Unsupported platform: $platform" popd From 0498c3ba64ace2bd8898a5d0ba3107a2f024c692 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev Date: Fri, 7 Oct 2016 00:47:28 +0300 Subject: [PATCH 15/42] Transaction history is not crashing and refreshing properly --- components/HistoryTable.qml | 7 ++++-- main.cpp | 6 ++++- main.qml | 26 ++++++++++++++++--- pages/History.qml | 5 ++-- src/libwalletqt/TransactionHistory.cpp | 35 +++++++++++++------------- src/libwalletqt/TransactionHistory.h | 6 ++--- src/libwalletqt/Wallet.cpp | 20 +++++++-------- src/libwalletqt/Wallet.h | 14 +++++++---- 8 files changed, 74 insertions(+), 45 deletions(-) diff --git a/components/HistoryTable.qml b/components/HistoryTable.qml index 13bf377580..441fbcf5b4 100644 --- a/components/HistoryTable.qml +++ b/components/HistoryTable.qml @@ -80,6 +80,7 @@ ListView { } // -- description aka recepient name from address book (TODO) + /* Text { id: descriptionText width: text.length ? (descriptionArea.containsMouse ? parent.width - x - 12 : 120) : 0 @@ -97,12 +98,14 @@ ListView { hoverEnabled: true } } - + */ + /* Item { //separator width: descriptionText.width ? 12 : 0 height: 14 visible: !descriptionArea.containsMouse } + */ // -- address (in case outgoing transaction) - N/A in case of incoming Text { id: addressText @@ -113,7 +116,7 @@ ListView { font.pixelSize: 14 color: "#545454" text: hash - visible: !descriptionArea.containsMouse + // visible: !descriptionArea.containsMouse } } // -- "PaymentID" title diff --git a/main.cpp b/main.cpp index 1709dc886a..9c87628f84 100644 --- a/main.cpp +++ b/main.cpp @@ -40,6 +40,7 @@ #include "PendingTransaction.h" #include "TranslationManager.h" #include "TransactionInfo.h" +#include "TransactionHistory.h" #include "model/TransactionHistoryModel.h" @@ -57,6 +58,7 @@ int main(int argc, char *argv[]) filter *eventFilter = new filter; app.installEventFilter(eventFilter); + // registering types for QML qmlRegisterType("moneroComponents.Clipboard", 1, 0, "Clipboard"); qmlRegisterUncreatableType("moneroComponents.Wallet", 1, 0, "Wallet", "Wallet can't be instantiated directly"); @@ -77,7 +79,9 @@ int main(int argc, char *argv[]) qmlRegisterUncreatableType("moneroComponents", 1, 0, "TransactionHistoryModel", - "TranslationManager can't be instantiated directly"); + "TransactionHistoryModel can't be instantiated directly"); + qmlRegisterUncreatableType("moneroComponents", 1, 0, "TransactionHistory", + "TransactionHistory can't be instantiated directly"); QQmlApplicationEngine engine; diff --git a/main.qml b/main.qml index d6d454099c..97ea573822 100644 --- a/main.qml +++ b/main.qml @@ -55,6 +55,8 @@ ApplicationWindow { property alias password : passwordDialog.password property int splashCounter: 0 property bool isNewWallet: false + // true if wallet ever synchronized + property bool walletInitialized : false function altKeyReleased() { ctrlPressed = false; } @@ -168,11 +170,10 @@ ApplicationWindow { currentWallet.refreshed.connect(onWalletRefresh) currentWallet.updated.connect(onWalletUpdate) currentWallet.newBlock.connect(onWalletNewBlock) - + currentWallet.moneySpent.connect(onWalletMoneySent) + currentWallet.moneyReceived.connect(onWalletMoneyReceived) console.log("initializing with daemon address: ", persistentSettings.daemon_address) - currentWallet.initAsync(persistentSettings.daemon_address, 0); - } function walletPath() { @@ -241,6 +242,13 @@ ApplicationWindow { console.log("wallet stored after first successfull refresh") } + // initialize transaction history once wallet is initializef first time; + if (!walletInitialized) { + currentWallet.history.refresh() + walletInitialized = true + + } + leftPanel.networkStatus.connected = currentWallet.connected onWalletUpdate(); @@ -258,6 +266,18 @@ ApplicationWindow { } } + function onWalletMoneyReceived(txId, amount) { + // refresh transaction history here + currentWallet.refresh() + currentWallet.history.refresh() // this will refresh model + } + + function onWalletMoneySent(txId, amount) { + // refresh transaction history here + currentWallet.refresh() + currentWallet.history.refresh() // this will refresh model + } + function walletsFound() { diff --git a/pages/History.qml b/pages/History.qml index 15cf1bc07d..d1934629fb 100644 --- a/pages/History.qml +++ b/pages/History.qml @@ -33,7 +33,7 @@ import moneroComponents.WalletManager 1.0 Rectangle { id: root - property var model: testModel + property var model color: "#F0EEEE" @@ -340,7 +340,7 @@ Rectangle { offset: 20 onSortRequest: console.log("column: " + column + " desc: " + desc) } - + /* ListModel { id: testModel ListElement { paymentId: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; address: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; date: "Jan 12, 2014"; time: "12:23 AM"; amount: "0.000709159241"; balance: "19301.870709159241"; description: "Client from Australia"; out: false } @@ -354,6 +354,7 @@ Rectangle { ListElement { paymentId: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; address: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; date: "Jan 12, 2014"; time: "12:23 AM"; amount: "0.000709159241"; balance: "19301.870709159241"; description: "Client from Australia"; out: false } ListElement { paymentId: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; address: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; date: "Jan 12, 2014"; time: "12:23 AM"; amount: "0.000709159241"; balance: "19301.870709159241"; description: ""; out: false } } + */ Scroll { id: flickableScroll diff --git a/src/libwalletqt/TransactionHistory.cpp b/src/libwalletqt/TransactionHistory.cpp index 8f52f07e10..e94816f2db 100644 --- a/src/libwalletqt/TransactionHistory.cpp +++ b/src/libwalletqt/TransactionHistory.cpp @@ -7,54 +7,53 @@ TransactionInfo *TransactionHistory::transaction(int index) { - // box up Bitmonero::TransactionInfo - Bitmonero::TransactionInfo * impl = m_pimpl->transaction(index); - if (!impl) { + + if (index < 0 || index >= m_tinfo.size()) { qCritical("%s: no transaction info for index %d", __FUNCTION__, index); qCritical("%s: there's %d transactions in backend", __FUNCTION__, m_pimpl->count()); return nullptr; } - TransactionInfo * result = new TransactionInfo(impl, this); - return result; + return m_tinfo.at(index); } -TransactionInfo *TransactionHistory::transaction(const QString &id) -{ - // box up Bitmonero::TransactionInfo - Bitmonero::TransactionInfo * impl = m_pimpl->transaction(id.toStdString()); - TransactionInfo * result = new TransactionInfo(impl, this); - return result; -} +//// XXX: not sure if this method really needed; +//TransactionInfo *TransactionHistory::transaction(const QString &id) +//{ +// return nullptr; +//} QList TransactionHistory::getAll() const { + // XXX this invalidates previously saved history that might be used by model + emit refreshStarted(); qDeleteAll(m_tinfo); m_tinfo.clear(); TransactionHistory * parent = const_cast(this); for (const auto i : m_pimpl->getAll()) { TransactionInfo * ti = new TransactionInfo(i, parent); + qDebug() << ti->hash(); m_tinfo.append(ti); } + emit refreshFinished(); return m_tinfo; } void TransactionHistory::refresh() { - // XXX this invalidates previously saved history that might be used by clients - - emit refreshStarted(); + // rebuilding transaction list in wallet_api; m_pimpl->refresh(); - emit refreshFinished(); + // copying list here and keep track on every item to avoid memleaks + getAll(); } quint64 TransactionHistory::count() const { - return m_pimpl->count(); + return m_tinfo.count(); } TransactionHistory::TransactionHistory(Bitmonero::TransactionHistory *pimpl, QObject *parent) : QObject(parent), m_pimpl(pimpl) { - + // this->refresh(); } diff --git a/src/libwalletqt/TransactionHistory.h b/src/libwalletqt/TransactionHistory.h index 560b8df806..d7a7278e02 100644 --- a/src/libwalletqt/TransactionHistory.h +++ b/src/libwalletqt/TransactionHistory.h @@ -17,14 +17,14 @@ class TransactionHistory : public QObject public: Q_INVOKABLE TransactionInfo *transaction(int index); - Q_INVOKABLE TransactionInfo * transaction(const QString &id); + // Q_INVOKABLE TransactionInfo * transaction(const QString &id); Q_INVOKABLE QList getAll() const; Q_INVOKABLE void refresh(); quint64 count() const; signals: - void refreshStarted(); - void refreshFinished(); + void refreshStarted() const; + void refreshFinished() const; public slots: diff --git a/src/libwalletqt/Wallet.cpp b/src/libwalletqt/Wallet.cpp index 39d40a17bf..14e0a86803 100644 --- a/src/libwalletqt/Wallet.cpp +++ b/src/libwalletqt/Wallet.cpp @@ -32,7 +32,6 @@ class WalletListenerImpl : public Bitmonero::WalletListener virtual void moneyReceived(const std::string &txId, uint64_t amount) { - qDebug() << __FUNCTION__; emit m_wallet->moneyReceived(QString::fromStdString(txId), amount); } @@ -40,14 +39,12 @@ class WalletListenerImpl : public Bitmonero::WalletListener virtual void newBlock(uint64_t height) { // qDebug() << __FUNCTION__; - m_wallet->m_history->refresh(); emit m_wallet->newBlock(height); } virtual void updated() { qDebug() << __FUNCTION__; - m_wallet->m_history->refresh(); emit m_wallet->updated(); } @@ -55,7 +52,6 @@ class WalletListenerImpl : public Bitmonero::WalletListener virtual void refreshed() { qDebug() << __FUNCTION__; - emit m_wallet->refreshed(); } @@ -93,6 +89,11 @@ bool Wallet::connected() const return m_walletImpl->connected(); } +bool Wallet::synchronized() const +{ + return m_walletImpl->synchronized(); +} + QString Wallet::errorString() const { return QString::fromStdString(m_walletImpl->errorString()); @@ -207,19 +208,16 @@ void Wallet::disposeTransaction(PendingTransaction *t) delete t; } -TransactionHistory *Wallet::history() +TransactionHistory *Wallet::history() const { -// if (m_history->count() == 0) { -// m_history->refresh(); -// } - return m_history; } -TransactionHistoryModel *Wallet::historyModel() +TransactionHistoryModel *Wallet::historyModel() const { if (!m_historyModel) { - m_historyModel = new TransactionHistoryModel(this); + Wallet * w = const_cast(this); + m_historyModel = new TransactionHistoryModel(w); m_historyModel->setTransactionHistory(this->history()); } diff --git a/src/libwalletqt/Wallet.h b/src/libwalletqt/Wallet.h index d3ca40856d..159a08b001 100644 --- a/src/libwalletqt/Wallet.h +++ b/src/libwalletqt/Wallet.h @@ -22,6 +22,7 @@ class Wallet : public QObject Q_PROPERTY(QString seedLanguage READ getSeedLanguage) Q_PROPERTY(Status status READ status) Q_PROPERTY(bool connected READ connected) + Q_PROPERTY(bool synchronized READ synchronized) Q_PROPERTY(QString errorString READ errorString) Q_PROPERTY(QString address READ address) Q_PROPERTY(quint64 balance READ balance) @@ -52,9 +53,13 @@ class Wallet : public QObject //! returns last operation's status Status status() const; - //! returns of wallet connected + //! returns true if wallet connected bool connected() const; + //! returns true if wallet was ever synchronized + bool synchronized() const; + + //! returns last operation's error message QString errorString() const; @@ -98,7 +103,6 @@ class Wallet : public QObject //! refreshes the wallet Q_INVOKABLE bool refresh(); - //! refreshes the wallet asynchronously Q_INVOKABLE void refreshAsync(); @@ -116,10 +120,10 @@ class Wallet : public QObject Q_INVOKABLE void disposeTransaction(PendingTransaction * t); //! returns transaction history - TransactionHistory * history(); + TransactionHistory * history() const; //! returns transaction history model - TransactionHistoryModel * historyModel(); + TransactionHistoryModel * historyModel() const; //! generate payment id Q_INVOKABLE QString generatePaymentId() const; @@ -160,7 +164,7 @@ class Wallet : public QObject // history lifetime managed by wallet; TransactionHistory * m_history; // Used for UI history view - TransactionHistoryModel * m_historyModel; + mutable TransactionHistoryModel * m_historyModel; QString m_paymentId; mutable QTime m_daemonBlockChainHeightTime; mutable quint64 m_daemonBlockChainHeight; From e7e6c583b676325d64e10cf75257c000e35cd344 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev Date: Fri, 7 Oct 2016 16:20:52 +0300 Subject: [PATCH 16/42] Adding sort-filter-proxy model --- src/model/TransactionHistorySortFilterModel.cpp | 6 ++++++ src/model/TransactionHistorySortFilterModel.h | 12 ++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 src/model/TransactionHistorySortFilterModel.cpp create mode 100644 src/model/TransactionHistorySortFilterModel.h diff --git a/src/model/TransactionHistorySortFilterModel.cpp b/src/model/TransactionHistorySortFilterModel.cpp new file mode 100644 index 0000000000..67d7b84a10 --- /dev/null +++ b/src/model/TransactionHistorySortFilterModel.cpp @@ -0,0 +1,6 @@ +#include "TransactionHistorySortFiltrerModel.h" + +TransactionHistorySortFiltrerModel::TransactionHistorySortFiltrerModel() +{ + +} diff --git a/src/model/TransactionHistorySortFilterModel.h b/src/model/TransactionHistorySortFilterModel.h new file mode 100644 index 0000000000..bdcab0796c --- /dev/null +++ b/src/model/TransactionHistorySortFilterModel.h @@ -0,0 +1,12 @@ +#ifndef TRANSACTIONHISTORYSORTFILTRERMODEL_H +#define TRANSACTIONHISTORYSORTFILTRERMODEL_H + +#include + +class TransactionHistorySortFiltrerModel : public QSortFilterProxyModel +{ +public: + TransactionHistorySortFiltrerModel(); +}; + +#endif // TRANSACTIONHISTORYSORTFILTRERMODEL_H \ No newline at end of file From 612c497608cc64234a05cd413d4269160f17100c Mon Sep 17 00:00:00 2001 From: Ilya Kitaev Date: Fri, 7 Oct 2016 23:05:51 +0300 Subject: [PATCH 17/42] 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 441fbcf5b4..0cca11487c 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 9c87628f84..58ca60f84d 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 6f21e6eaa9..daa1378d34 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 d1934629fb..f8337c5be4 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 3aa7334cb1..248fd73ed6 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 3381131ad8..b614dfc8cd 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 @@ class TransactionInfo : public QObject 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 14e0a86803..b52963bcbe 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 159a08b001..f9bca5a378 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 @@ class Wallet : public QObject 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 @@ class Wallet : public QObject 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 b8f23f68af..1ad17944b0 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 96d3ff329e..0960ceae2c 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 @@ class TransactionHistoryModel : public QAbstractListModel TransactionPendingRole, TransactionFailedRole, TransactionAmountRole, + TransactionDisplayAmountRole, TransactionFeeRole, TransactionBlockHeightRole, TransactionHashRole, @@ -32,10 +34,24 @@ class TransactionHistoryModel : public QAbstractListModel 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 @@ class TransactionHistoryModel : public QAbstractListModel private: TransactionHistory * m_transactionHistory; - }; #endif // TRANSACTIONHISTORYMODEL_H diff --git a/src/model/TransactionHistorySortFilterModel.cpp b/src/model/TransactionHistorySortFilterModel.cpp index 67d7b84a10..946137c6bd 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 bdcab0796c..c1d3d2c2b7 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 f0344a94d8..8506a8e71c 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 cc8a5be3d4..ede68b1352 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) From fd9ed56c545ae312bedaf26fd1f56b0070e86889 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev Date: Sat, 8 Oct 2016 01:20:55 +0300 Subject: [PATCH 18/42] Fix: DatePicker component doesn't update the date --- components/DatePicker.qml | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/components/DatePicker.qml b/components/DatePicker.qml index 442ecdb0e2..9d0cbf20c0 100644 --- a/components/DatePicker.qml +++ b/components/DatePicker.qml @@ -33,12 +33,13 @@ import QtQuick.Controls.Styles 1.2 Item { id: datePicker property bool expanded: false - property var currentDate: new Date() + property date currentDate property bool showCurrentDate: true height: 37 width: 156 onExpandedChanged: if(expanded) appWindow.currentItem = datePicker + function hide() { datePicker.expanded = false } function containsPoint(px, py) { if(px < 0) @@ -121,12 +122,29 @@ Item { } Row { + id: dateInput anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left anchors.leftMargin: 10 + function setDate(date) { + var day = date.getDate() + var month = date.getMonth() + 1 + dayInput.text = day < 10 ? "0" + day : day + monthInput.text = month < 10 ? "0" + month : month + yearInput.text = date.getFullYear() + } + + Connections { + target: datePicker + onCurrentDateChanged: { + dateInput.setDate(datePicker.currentDate) + } + } + TextInput { id: dayInput + readOnly: true width: 22 font.family: "Arial" font.pixelSize: 18 @@ -135,6 +153,7 @@ Item { horizontalAlignment: TextInput.AlignHCenter validator: IntValidator{bottom: 01; top: 31;} KeyNavigation.tab: monthInput + text: { if(datePicker.showCurrentDate) { var day = datePicker.currentDate.getDate() @@ -158,6 +177,7 @@ Item { TextInput { id: monthInput + readOnly: true width: 22 font.family: "Arial" font.pixelSize: 18 @@ -277,12 +297,7 @@ Item { anchors.fill: parent onClicked: { if(styleData.visibleMonth) { - var date = styleData.date - var day = date.getDate() - var month = date.getMonth() + 1 - dayInput.text = day < 10 ? "0" + day : day - monthInput.text = month < 10 ? "0" + month : month - yearInput.text = date.getFullYear() + currentDate = styleData.date datePicker.expanded = false } else { var date = styleData.date From 99271828aeec560984feda1c3d4c8b179b778cf5 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev Date: Sat, 8 Oct 2016 01:21:27 +0300 Subject: [PATCH 19/42] Fix: unused dummy property removed --- main.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/main.qml b/main.qml index 97ea573822..214686da12 100644 --- a/main.qml +++ b/main.qml @@ -55,6 +55,7 @@ ApplicationWindow { property alias password : passwordDialog.password property int splashCounter: 0 property bool isNewWallet: false + // true if wallet ever synchronized property bool walletInitialized : false From e3cea8582f1f860ba2a25bbfb174fbcbcd306c9a Mon Sep 17 00:00:00 2001 From: Ilya Kitaev Date: Sat, 8 Oct 2016 01:22:45 +0300 Subject: [PATCH 20/42] TransactionHistory: firstDateTime and lastDateTime properties --- src/libwalletqt/TransactionHistory.cpp | 35 ++++++++++++++++++++++++-- src/libwalletqt/TransactionHistory.h | 9 +++++++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/libwalletqt/TransactionHistory.cpp b/src/libwalletqt/TransactionHistory.cpp index e94816f2db..7fd7c7bc9e 100644 --- a/src/libwalletqt/TransactionHistory.cpp +++ b/src/libwalletqt/TransactionHistory.cpp @@ -28,13 +28,33 @@ QList TransactionHistory::getAll() const emit refreshStarted(); qDeleteAll(m_tinfo); m_tinfo.clear(); + + QDateTime firstDateTime = QDateTime::currentDateTime(); + QDateTime lastDateTime = QDateTime(QDate(1970, 1, 1)); + TransactionHistory * parent = const_cast(this); for (const auto i : m_pimpl->getAll()) { TransactionInfo * ti = new TransactionInfo(i, parent); - qDebug() << ti->hash(); m_tinfo.append(ti); + // looking for transactions timestamp scope + if (ti->timestamp() >= lastDateTime) { + lastDateTime = ti->timestamp(); + } + if (ti->timestamp() <= firstDateTime) { + firstDateTime = ti->timestamp(); + } } emit refreshFinished(); + + if (m_firstDateTime != firstDateTime) { + m_firstDateTime = firstDateTime; + emit firstDateTimeChanged(); + } + if (m_lastDateTime != lastDateTime) { + m_lastDateTime = lastDateTime; + emit lastDateTimeChanged(); + } + return m_tinfo; } @@ -51,9 +71,20 @@ quint64 TransactionHistory::count() const return m_tinfo.count(); } +QDateTime TransactionHistory::firstDateTime() const +{ + return m_firstDateTime; +} + +QDateTime TransactionHistory::lastDateTime() const +{ + return m_lastDateTime; +} + TransactionHistory::TransactionHistory(Bitmonero::TransactionHistory *pimpl, QObject *parent) : QObject(parent), m_pimpl(pimpl) { - // this->refresh(); + m_firstDateTime = QDateTime(QDate(1970, 1, 1)); + m_lastDateTime = QDateTime::currentDateTime(); } diff --git a/src/libwalletqt/TransactionHistory.h b/src/libwalletqt/TransactionHistory.h index d7a7278e02..ee05787a54 100644 --- a/src/libwalletqt/TransactionHistory.h +++ b/src/libwalletqt/TransactionHistory.h @@ -3,6 +3,7 @@ #include #include +#include namespace Bitmonero { class TransactionHistory; @@ -14,6 +15,8 @@ class TransactionHistory : public QObject { Q_OBJECT Q_PROPERTY(int count READ count) + Q_PROPERTY(QDateTime firstDateTime READ firstDateTime NOTIFY firstDateTimeChanged) + Q_PROPERTY(QDateTime lastDateTime READ lastDateTime NOTIFY lastDateTimeChanged) public: Q_INVOKABLE TransactionInfo *transaction(int index); @@ -21,10 +24,14 @@ class TransactionHistory : public QObject Q_INVOKABLE QList getAll() const; Q_INVOKABLE void refresh(); quint64 count() const; + QDateTime firstDateTime() const; + QDateTime lastDateTime() const; signals: void refreshStarted() const; void refreshFinished() const; + void firstDateTimeChanged() const; + void lastDateTimeChanged() const; public slots: @@ -37,6 +44,8 @@ public slots: Bitmonero::TransactionHistory * m_pimpl; mutable QList m_tinfo; + mutable QDateTime m_firstDateTime; + mutable QDateTime m_lastDateTime; }; From 9b09e83ba0056364f99fa7a9e02a4181ac7d343d Mon Sep 17 00:00:00 2001 From: Ilya Kitaev Date: Sat, 8 Oct 2016 01:24:18 +0300 Subject: [PATCH 21/42] History: filtering by paymentId and date --- pages/History.qml | 32 +++---- src/libwalletqt/Wallet.h | 3 +- .../TransactionHistorySortFilterModel.cpp | 85 ++++++++++++++++++- src/model/TransactionHistorySortFilterModel.h | 27 +++++- 4 files changed, 125 insertions(+), 22 deletions(-) diff --git a/pages/History.qml b/pages/History.qml index f8337c5be4..269c06a41c 100644 --- a/pages/History.qml +++ b/pages/History.qml @@ -42,7 +42,11 @@ Rectangle { color: "#F0EEEE" onModelChanged: { - console.log("model.rowCount: " + model.rowCount()) + if (typeof model !== 'undefined') { + // setup date filter scope according to real transactions + fromDatePicker.currentDate = model.transactionHistory.firstDateTime + toDatePicker.currentDate = model.transactionHistory.lastDateTime + } } @@ -107,6 +111,8 @@ Rectangle { anchors.leftMargin: 17 anchors.rightMargin: 17 anchors.topMargin: 5 + + } // Filter by description input (not implemented yet) @@ -154,6 +160,9 @@ Rectangle { anchors.leftMargin: 17 anchors.topMargin: 5 z: 2 + onCurrentDateChanged: { + console.log("CurrentDate: " + currentDate) + } } // DateTo picker @@ -188,6 +197,12 @@ Rectangle { shadowPressedColor: "#2D002F" releasedColor: "#6B0072" pressedColor: "#4D0051" + onClicked: { + // Apply filter here; + model.paymentIdFilter = paymentIdLine.text + model.dateFromFilter = fromDatePicker.currentDate + model.dateToFilter = toDatePicker.currentDate + } } CheckBox { @@ -373,21 +388,6 @@ Rectangle { model.sort(0, desc ? Qt.DescendingOrder : Qt.AscendingOrder) } } - /* - ListModel { - id: testModel - ListElement { paymentId: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; address: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; date: "Jan 12, 2014"; time: "12:23 AM"; amount: "0.000709159241"; balance: "19301.870709159241"; description: "Client from Australia"; out: false } - ListElement { paymentId: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; address: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; date: "Jan 12, 2014"; time: "12:23 AM"; amount: "0.000709159241"; balance: "19301.870709159241"; description: ""; out: true } - ListElement { paymentId: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; address: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; date: "Jan 12, 2014"; time: "12:23 AM"; amount: "0.000709159241"; balance: "19301.870709159241"; description: ""; out: true } - ListElement { paymentId: ""; address: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; date: "Jan 12, 2014"; time: "12:23 AM"; amount: "0.000709159241"; balance: "19301.870709159241"; description: ""; out: false } - ListElement { paymentId: ""; address: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; date: "Jan 12, 2014"; time: "12:23 AM"; amount: "0.000709159241"; balance: "19301.870709159241"; description: "Client from Australia"; out: false } - ListElement { paymentId: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; address: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; date: "Jan 12, 2014"; time: "12:23 AM"; amount: "0.000709159241"; balance: "19301.870709159241"; description: ""; out: false } - ListElement { paymentId: ""; address: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; date: "Jan 12, 2014"; time: "12:23 AM"; amount: "0.000709159241"; balance: "19301.870709159241"; description: ""; out: false } - ListElement { paymentId: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; address: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; date: "Jan 12, 2014"; time: "12:23 AM"; amount: "0.000709159241"; balance: "19301.870709159241"; description: ""; out: false } - ListElement { paymentId: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; address: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; date: "Jan 12, 2014"; time: "12:23 AM"; amount: "0.000709159241"; balance: "19301.870709159241"; description: "Client from Australia"; out: false } - ListElement { paymentId: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; address: "faef56b9acf67a7dba75ec01f403497049d7cff111628edfe7b57278554dc798"; date: "Jan 12, 2014"; time: "12:23 AM"; amount: "0.000709159241"; balance: "19301.870709159241"; description: ""; out: false } - } - */ Scroll { id: flickableScroll diff --git a/src/libwalletqt/Wallet.h b/src/libwalletqt/Wallet.h index f9bca5a378..d794550a9d 100644 --- a/src/libwalletqt/Wallet.h +++ b/src/libwalletqt/Wallet.h @@ -30,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(TransactionHistorySortFilterModel * historyModel READ historyModel) + Q_PROPERTY(TransactionHistorySortFilterModel * historyModel READ historyModel NOTIFY historyModelChanged) public: @@ -151,6 +151,7 @@ class Wallet : public QObject void moneySpent(const QString &txId, quint64 amount); void moneyReceived(const QString &txId, quint64 amount); void newBlock(quint64 height); + void historyModelChanged() const; private: diff --git a/src/model/TransactionHistorySortFilterModel.cpp b/src/model/TransactionHistorySortFilterModel.cpp index 946137c6bd..8cdcff6c03 100644 --- a/src/model/TransactionHistorySortFilterModel.cpp +++ b/src/model/TransactionHistorySortFilterModel.cpp @@ -6,17 +6,49 @@ TransactionHistorySortFilterModel::TransactionHistorySortFilterModel(QObject *parent) : QSortFilterProxyModel(parent) { - + setDynamicSortFilter(true); } QString TransactionHistorySortFilterModel::paymentIdFilter() const { - + return m_filterValues.value(TransactionHistoryModel::TransactionPaymentIdRole).toString(); } void TransactionHistorySortFilterModel::setPaymentIdFilter(const QString &arg) { + if (paymentIdFilter() != arg) { + m_filterValues[TransactionHistoryModel::TransactionPaymentIdRole] = arg; + emit paymentIdFilterChanged(); + invalidateFilter(); + } +} + +QDate TransactionHistorySortFilterModel::dateFromFilter() const +{ + return dateFromToFilter(From); +} +void TransactionHistorySortFilterModel::setDateFromFilter(const QDate &date) +{ + if (date != dateFromFilter()) { + setDateFromToFilter(From, date); + emit dateFromFilterChanged(); + invalidateFilter(); + } +} + +QDate TransactionHistorySortFilterModel::dateToFilter() const +{ + return dateFromToFilter(To); +} + +void TransactionHistorySortFilterModel::setDateToFilter(const QDate &date) +{ + if (date != dateToFilter()) { + setDateFromToFilter(To, date); + emit dateFromFilterChanged(); + invalidateFilter(); + } } void TransactionHistorySortFilterModel::sort(int column, Qt::SortOrder order) @@ -24,6 +56,12 @@ void TransactionHistorySortFilterModel::sort(int column, Qt::SortOrder order) QSortFilterProxyModel::sort(column, order); } +TransactionHistory *TransactionHistorySortFilterModel::transactionHistory() const +{ + const TransactionHistoryModel * model = static_cast (sourceModel()); + return model->transactionHistory(); +} + bool TransactionHistorySortFilterModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const { @@ -38,11 +76,27 @@ bool TransactionHistorySortFilterModel::filterAcceptsRow(int source_row, const Q bool result = true; + // iterating through filters 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) + switch (role) { + case TransactionHistoryModel::TransactionPaymentIdRole: + result = data.toString().contains(paymentIdFilter()); + break; + case TransactionHistoryModel::TransactionTimeStampRole: + { + QDateTime from = QDateTime(dateFromFilter()); + QDateTime to = QDateTime(dateToFilter()); + QDateTime timestamp = data.toDateTime(); + bool matchFrom = from.isNull() || timestamp.isNull() || timestamp >= from; + bool matchTo = to.isNull() || timestamp.isNull() || timestamp <= to; + result = matchFrom && matchTo; + } + default: + break; + } + if (!result) // stop the loop once filter doesn't match break; } } @@ -64,3 +118,26 @@ void TransactionHistorySortFilterModel::setFilterValue(int role, const QVariant { m_filterValues[role] = filterValue; } + +QDate TransactionHistorySortFilterModel::dateFromToFilter(TransactionHistorySortFilterModel::DateScopeIndex index) const +{ + int role = TransactionHistoryModel::TransactionTimeStampRole; + if (!m_filterValues.contains(role)) { + return QDate(); + } + return m_filterValues.value(role).toList().at(index).toDate(); +} + +void TransactionHistorySortFilterModel::setDateFromToFilter(TransactionHistorySortFilterModel::DateScopeIndex index, const QDate &value) +{ + QVariantList scopeFilter; + int role = TransactionHistoryModel::TransactionTimeStampRole; + if (m_filterValues.contains(role)) { + scopeFilter = m_filterValues.value(role).toList(); + } + while (scopeFilter.size() < 2) { + scopeFilter.append(QDate()); + } + scopeFilter[index] = QVariant::fromValue(value); + m_filterValues[role] = scopeFilter; +} diff --git a/src/model/TransactionHistorySortFilterModel.h b/src/model/TransactionHistorySortFilterModel.h index c1d3d2c2b7..541714b86d 100644 --- a/src/model/TransactionHistorySortFilterModel.h +++ b/src/model/TransactionHistorySortFilterModel.h @@ -5,18 +5,36 @@ #include #include #include +#include +class TransactionHistory; class TransactionHistorySortFilterModel: public QSortFilterProxyModel { -Q_OBJECT + Q_OBJECT + Q_PROPERTY(QString paymentIdFilter READ paymentIdFilter WRITE setPaymentIdFilter NOTIFY paymentIdFilterChanged) + Q_PROPERTY(QDate dateFromFilter READ dateFromFilter WRITE setDateFromFilter NOTIFY dateFromFilterChanged) + Q_PROPERTY(QDate dateToFilter READ dateToFilter WRITE setDateToFilter NOTIFY dateToFilterChanged) + Q_PROPERTY(TransactionHistory * transactionHistory READ transactionHistory) + public: TransactionHistorySortFilterModel(QObject * parent = nullptr); QString paymentIdFilter() const; void setPaymentIdFilter(const QString &arg); + QDate dateFromFilter() const; + void setDateFromFilter(const QDate &date); + QDate dateToFilter() const; + void setDateToFilter(const QDate &date); Q_INVOKABLE void sort(int column, Qt::SortOrder order); + TransactionHistory * transactionHistory() const; + +signals: + void paymentIdFilterChanged(); + void dateFromFilterChanged(); + void dateToFilterChanged(); + protected: // QSortFilterProxyModel overrides virtual bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const; @@ -24,8 +42,15 @@ Q_OBJECT private: + enum DateScopeIndex { + From = 0, + To = 1 + }; + QVariant filterValue(int role); void setFilterValue(int role, const QVariant &filterValue); + QDate dateFromToFilter(DateScopeIndex index) const; + void setDateFromToFilter(DateScopeIndex index, const QDate &value); private: QMap m_filterValues; From 8b748bf25ddb459e6291d124fedcb80fa05445d3 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev Date: Sat, 8 Oct 2016 02:28:27 +0300 Subject: [PATCH 22/42] History: filter by amount --- pages/History.qml | 20 ++-- .../TransactionHistorySortFilterModel.cpp | 92 +++++++++++++++++-- src/model/TransactionHistorySortFilterModel.h | 27 +++++- 3 files changed, 123 insertions(+), 16 deletions(-) diff --git a/pages/History.qml b/pages/History.qml index 269c06a41c..e76fa5c961 100644 --- a/pages/History.qml +++ b/pages/History.qml @@ -160,9 +160,6 @@ Rectangle { anchors.leftMargin: 17 anchors.topMargin: 5 z: 2 - onCurrentDateChanged: { - console.log("CurrentDate: " + currentDate) - } } // DateTo picker @@ -202,11 +199,21 @@ Rectangle { model.paymentIdFilter = paymentIdLine.text model.dateFromFilter = fromDatePicker.currentDate model.dateToFilter = toDatePicker.currentDate + if (advancedFilteringCheckBox.checked) { + if (amountFromLine.text.length) { + model.amountFromFilter = parseFloat(amountFromLine.text) + } + if (amountToLine.text.length) { + model.amountToFilter = parseFloat(amountToLine.text) + } + } + + } } CheckBox { - id: checkBox + id: advancedFilteringCheckBox text: qsTr("Advance filtering") anchors.left: filterButton.right anchors.bottom: filterButton.bottom @@ -233,9 +240,10 @@ Rectangle { ListModel { id: transactionsModel + ListElement { column1: "ALL"; column2: "" } ListElement { column1: "SENT"; column2: "" } - ListElement { column1: "RECIVE"; column2: "" } - ListElement { column1: "ON HOLD"; column2: "" } + ListElement { column1: "RECEIVED"; column2: "" } + } StandardDropdown { diff --git a/src/model/TransactionHistorySortFilterModel.cpp b/src/model/TransactionHistorySortFilterModel.cpp index 8cdcff6c03..d06d44bff7 100644 --- a/src/model/TransactionHistorySortFilterModel.cpp +++ b/src/model/TransactionHistorySortFilterModel.cpp @@ -3,6 +3,39 @@ #include +namespace { + /** + * helper to extract scope value from filter + */ + template + T scopeFilterValue(const QMap &filters, int role, int scopeIndex) + { + if (!filters.contains(role)) { + return T(); + } + return filters.value(role).toList().at(scopeIndex).value(); + } + + /** + * helper to setup scope value to filter + */ + template + void setScopeFilterValue(QMap &filters, int role, int scopeIndex, const T &value) + { + QVariantList scopeFilter; + + if (filters.contains(role)) { + scopeFilter = filters.value(role).toList(); + } + while (scopeFilter.size() < 2) { + scopeFilter.append(T()); + } + scopeFilter[scopeIndex] = QVariant::fromValue(value); + filters[role] = scopeFilter; + } +} + + TransactionHistorySortFilterModel::TransactionHistorySortFilterModel(QObject *parent) : QSortFilterProxyModel(parent) { @@ -25,13 +58,13 @@ void TransactionHistorySortFilterModel::setPaymentIdFilter(const QString &arg) QDate TransactionHistorySortFilterModel::dateFromFilter() const { - return dateFromToFilter(From); + return scopeFilterValue(m_filterValues, TransactionHistoryModel::TransactionTimeStampRole, ScopeIndex::From); } void TransactionHistorySortFilterModel::setDateFromFilter(const QDate &date) { if (date != dateFromFilter()) { - setDateFromToFilter(From, date); + setScopeFilterValue(m_filterValues, TransactionHistoryModel::TransactionTimeStampRole, ScopeIndex::From, date); emit dateFromFilterChanged(); invalidateFilter(); } @@ -39,18 +72,47 @@ void TransactionHistorySortFilterModel::setDateFromFilter(const QDate &date) QDate TransactionHistorySortFilterModel::dateToFilter() const { - return dateFromToFilter(To); + return scopeFilterValue(m_filterValues, TransactionHistoryModel::TransactionTimeStampRole, ScopeIndex::To); } void TransactionHistorySortFilterModel::setDateToFilter(const QDate &date) { if (date != dateToFilter()) { - setDateFromToFilter(To, date); - emit dateFromFilterChanged(); + setScopeFilterValue(m_filterValues, TransactionHistoryModel::TransactionTimeStampRole, ScopeIndex::To, date); + emit dateToFilterChanged(); + invalidateFilter(); + } +} + +double TransactionHistorySortFilterModel::amountFromFilter() const +{ + return scopeFilterValue(m_filterValues, TransactionHistoryModel::TransactionAmountRole, ScopeIndex::From); +} + +void TransactionHistorySortFilterModel::setAmountFromFilter(double value) +{ + if (value != amountFromFilter()) { + setScopeFilterValue(m_filterValues, TransactionHistoryModel::TransactionAmountRole, ScopeIndex::From, value); + emit amountFromFilterChanged(); invalidateFilter(); } } +double TransactionHistorySortFilterModel::amountToFilter() const +{ + return scopeFilterValue(m_filterValues, TransactionHistoryModel::TransactionAmountRole, ScopeIndex::To); +} + +void TransactionHistorySortFilterModel::setAmountToFilter(double value) +{ + if (value != amountToFilter()) { + setScopeFilterValue(m_filterValues, TransactionHistoryModel::TransactionAmountRole, ScopeIndex::To, value); + emit amountToFilterChanged(); + invalidateFilter(); + } +} + + void TransactionHistorySortFilterModel::sort(int column, Qt::SortOrder order) { QSortFilterProxyModel::sort(column, order); @@ -93,9 +155,22 @@ bool TransactionHistorySortFilterModel::filterAcceptsRow(int source_row, const Q bool matchTo = to.isNull() || timestamp.isNull() || timestamp <= to; result = matchFrom && matchTo; } + break; + case TransactionHistoryModel::TransactionAmountRole: + { + double from = amountFromFilter(); + double to = amountToFilter(); + double amount = data.toDouble(); + + bool matchFrom = from < 0 || amount >= from; + bool matchTo = to < 0 || amount <= to; + result = matchFrom && matchTo; + } + break; default: break; } + if (!result) // stop the loop once filter doesn't match break; } @@ -119,7 +194,7 @@ void TransactionHistorySortFilterModel::setFilterValue(int role, const QVariant m_filterValues[role] = filterValue; } -QDate TransactionHistorySortFilterModel::dateFromToFilter(TransactionHistorySortFilterModel::DateScopeIndex index) const +QDate TransactionHistorySortFilterModel::dateFromToFilter(TransactionHistorySortFilterModel::ScopeIndex index) const { int role = TransactionHistoryModel::TransactionTimeStampRole; if (!m_filterValues.contains(role)) { @@ -128,7 +203,7 @@ QDate TransactionHistorySortFilterModel::dateFromToFilter(TransactionHistorySort return m_filterValues.value(role).toList().at(index).toDate(); } -void TransactionHistorySortFilterModel::setDateFromToFilter(TransactionHistorySortFilterModel::DateScopeIndex index, const QDate &value) +void TransactionHistorySortFilterModel::setDateFromToFilter(TransactionHistorySortFilterModel::ScopeIndex index, const QDate &value) { QVariantList scopeFilter; int role = TransactionHistoryModel::TransactionTimeStampRole; @@ -141,3 +216,6 @@ void TransactionHistorySortFilterModel::setDateFromToFilter(TransactionHistorySo scopeFilter[index] = QVariant::fromValue(value); m_filterValues[role] = scopeFilter; } + + + diff --git a/src/model/TransactionHistorySortFilterModel.h b/src/model/TransactionHistorySortFilterModel.h index 541714b86d..43c46a7b26 100644 --- a/src/model/TransactionHistorySortFilterModel.h +++ b/src/model/TransactionHistorySortFilterModel.h @@ -15,17 +15,32 @@ class TransactionHistorySortFilterModel: public QSortFilterProxyModel Q_PROPERTY(QString paymentIdFilter READ paymentIdFilter WRITE setPaymentIdFilter NOTIFY paymentIdFilterChanged) Q_PROPERTY(QDate dateFromFilter READ dateFromFilter WRITE setDateFromFilter NOTIFY dateFromFilterChanged) Q_PROPERTY(QDate dateToFilter READ dateToFilter WRITE setDateToFilter NOTIFY dateToFilterChanged) + Q_PROPERTY(double amountFromFilter READ amountFromFilter WRITE setAmountFromFilter NOTIFY amountFromFilterChanged) + Q_PROPERTY(double amountToFilter READ amountToFilter WRITE setAmountToFilter NOTIFY amountToFilterChanged) Q_PROPERTY(TransactionHistory * transactionHistory READ transactionHistory) public: TransactionHistorySortFilterModel(QObject * parent = nullptr); + //! filtering by payment id QString paymentIdFilter() const; void setPaymentIdFilter(const QString &arg); + + //! filtering by date (lower bound) QDate dateFromFilter() const; void setDateFromFilter(const QDate &date); + + //! filtering by to date (upper bound) QDate dateToFilter() const; void setDateToFilter(const QDate &date); + //! filtering by amount (lower bound) + double amountFromFilter() const; + void setAmountFromFilter(double value); + + //! filtering by amount (upper bound) + double amountToFilter() const; + void setAmountToFilter(double value); + Q_INVOKABLE void sort(int column, Qt::SortOrder order); TransactionHistory * transactionHistory() const; @@ -34,6 +49,8 @@ class TransactionHistorySortFilterModel: public QSortFilterProxyModel void paymentIdFilterChanged(); void dateFromFilterChanged(); void dateToFilterChanged(); + void amountFromFilterChanged(); + void amountToFilterChanged(); protected: // QSortFilterProxyModel overrides @@ -42,15 +59,19 @@ class TransactionHistorySortFilterModel: public QSortFilterProxyModel private: - enum DateScopeIndex { + enum ScopeIndex { From = 0, To = 1 }; QVariant filterValue(int role); void setFilterValue(int role, const QVariant &filterValue); - QDate dateFromToFilter(DateScopeIndex index) const; - void setDateFromToFilter(DateScopeIndex index, const QDate &value); + QDate dateFromToFilter(ScopeIndex index) const; + void setDateFromToFilter(ScopeIndex index, const QDate &value); +// double amountFromToFilter(ScopeIndex index) const; +// void setAmountFromToFilter(ScopeIndex index, double value); + + private: QMap m_filterValues; From 49018390dc121c390ecec1c81891cf4902dd9aeb Mon Sep 17 00:00:00 2001 From: Jacob Brydolf Date: Tue, 4 Oct 2016 22:22:59 +0200 Subject: [PATCH 23/42] added comma/locale separation to sync counter --- main.qml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/main.qml b/main.qml index 214686da12..a87def235d 100644 --- a/main.qml +++ b/main.qml @@ -260,7 +260,10 @@ ApplicationWindow { var currHeight = blockHeight.toFixed(0) if(currHeight > splashCounter + 1000){ splashCounter = currHeight - var progressText = qsTr("Synchronizing blocks %1/%2").arg(currHeight).arg(currentWallet.daemonBlockChainHeight().toFixed(0)); + var locale = Qt.locale() + var currHeightString = currHeight.toLocaleString(locale,"f",0) + var targetHeightString = currentWallet.daemonBlockChainHeight().toLocaleString(locale,"f",0) + var progressText = qsTr("Synchronizing blocks %1/%2").arg(currHeightString).arg(targetHeightString); console.log("Progress text: " + progressText); splash.heightProgressText = progressText } From 868610c7781efd6b3329cc0e0c44b7694759c11b Mon Sep 17 00:00:00 2001 From: Jacob Brydolf Date: Fri, 7 Oct 2016 16:44:20 +0200 Subject: [PATCH 24/42] fix conflict --- main.qml | 1 - 1 file changed, 1 deletion(-) diff --git a/main.qml b/main.qml index a87def235d..cf223bd54f 100644 --- a/main.qml +++ b/main.qml @@ -55,7 +55,6 @@ ApplicationWindow { property alias password : passwordDialog.password property int splashCounter: 0 property bool isNewWallet: false - // true if wallet ever synchronized property bool walletInitialized : false From 38db5a4178dad8ac933f013e22e3ee3e20e22fe7 Mon Sep 17 00:00:00 2001 From: Jacob Brydolf Date: Sat, 8 Oct 2016 01:37:47 +0200 Subject: [PATCH 25/42] Integrate splash counter with restore-height --- main.qml | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/main.qml b/main.qml index cf223bd54f..e0324e6e7f 100644 --- a/main.qml +++ b/main.qml @@ -55,6 +55,8 @@ ApplicationWindow { property alias password : passwordDialog.password property int splashCounter: 0 property bool isNewWallet: false + property int restoreHeight:0 + // true if wallet ever synchronized property bool walletInitialized : false @@ -150,7 +152,15 @@ ApplicationWindow { // wallet already opened with wizard, we just need to initialize it if (typeof wizard.settings['wallet'] !== 'undefined') { console.log("using wizard wallet") + //Set restoreHeight + if(persistentSettings.restoreHeight > 0){ + restoreHeight = persistentSettings.restoreHeight + } + + console.log("using wizard wallet") + connectWallet(wizard.settings['wallet']) + isNewWallet = true // We don't need the wizard wallet any more - delete to avoid conflict with daemon adress change delete wizard.settings['wallet'] @@ -242,11 +252,22 @@ ApplicationWindow { console.log("wallet stored after first successfull refresh") } + var dCurrentBlock = currentWallet.daemonBlockChainHeight(); + var dTargetBlock = currentWallet.daemonBlockChainTargetHeight(); + leftPanel.daemonProgress.updateProgress(dCurrentBlock,dTargetBlock); + + // Store wallet after first refresh. To prevent broken wallet after a crash + // TODO: Move this to libwallet? + if(isNewWallet && currentWallet.blockChainHeight() > 0){ + currentWallet.store(persistentSettings.wallet_path) + isNewWallet = false + console.log("wallet stored after first successfull refresh") + } + // initialize transaction history once wallet is initializef first time; if (!walletInitialized) { currentWallet.history.refresh() walletInitialized = true - } leftPanel.networkStatus.connected = currentWallet.connected @@ -256,8 +277,12 @@ ApplicationWindow { function onWalletNewBlock(blockHeight) { if (splash.visible) { - var currHeight = blockHeight.toFixed(0) - if(currHeight > splashCounter + 1000){ + var currHeight = blockHeight + + //fast refresh until restoreHeight is reached + var increment = ((restoreHeight == 0) || currHeight < restoreHeight)? 1000 : 10 + + if(currHeight > splashCounter + increment){ splashCounter = currHeight var locale = Qt.locale() var currHeightString = currHeight.toLocaleString(locale,"f",0) @@ -433,6 +458,7 @@ ApplicationWindow { property bool testnet: true property string daemon_address: "localhost:38081" property string payment_id + property int restoreHeight:0 } // TODO: replace with customized popups From 0e0b0bec8d4389c24cd18014c6866c189f47fe12 Mon Sep 17 00:00:00 2001 From: Jacob Brydolf Date: Sat, 8 Oct 2016 01:39:31 +0200 Subject: [PATCH 26/42] removed moneroComponets dependency --- pages/Settings.qml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pages/Settings.qml b/pages/Settings.qml index 699ec672ac..629d06ade6 100644 --- a/pages/Settings.qml +++ b/pages/Settings.qml @@ -34,9 +34,10 @@ import QtQuick.Dialogs 1.2 import "../components" -import moneroComponents 1.0 + import moneroComponents.Clipboard 1.0 + Rectangle { property var daemonAddress From 9f336a5c514adefabfb29b2f3807af862435aee1 Mon Sep 17 00:00:00 2001 From: Jacob Brydolf Date: Sat, 8 Oct 2016 01:45:17 +0200 Subject: [PATCH 27/42] libwalletqt: added restore-height parameter to recoveryWallet(); --- src/libwalletqt/WalletManager.cpp | 4 ++-- src/libwalletqt/WalletManager.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libwalletqt/WalletManager.cpp b/src/libwalletqt/WalletManager.cpp index ea299cdc3f..2e1fe57b9b 100644 --- a/src/libwalletqt/WalletManager.cpp +++ b/src/libwalletqt/WalletManager.cpp @@ -61,9 +61,9 @@ void WalletManager::openWalletAsync(const QString &path, const QString &password } -Wallet *WalletManager::recoveryWallet(const QString &path, const QString &memo, bool testnet) +Wallet *WalletManager::recoveryWallet(const QString &path, const QString &memo, bool testnet, quint64 restoreHeight) { - Bitmonero::Wallet * w = m_pimpl->recoveryWallet(path.toStdString(), memo.toStdString(), testnet); + Bitmonero::Wallet * w = m_pimpl->recoveryWallet(path.toStdString(), memo.toStdString(), testnet, restoreHeight); Wallet * wallet = new Wallet(w); return wallet; } diff --git a/src/libwalletqt/WalletManager.h b/src/libwalletqt/WalletManager.h index 23c569250b..24fb60fc84 100644 --- a/src/libwalletqt/WalletManager.h +++ b/src/libwalletqt/WalletManager.h @@ -48,7 +48,7 @@ class WalletManager : public QObject // wizard: recoveryWallet path; hint: internally it recorvers wallet and set password = "" Q_INVOKABLE Wallet * recoveryWallet(const QString &path, const QString &memo, - bool testnet = false); + bool testnet = false, quint64 restoreHeight = 0); /*! * \brief closeWallet - closes wallet and frees memory From 7f0d6c4c2861b445b15d0c1a4f8b0bf3f25f0886 Mon Sep 17 00:00:00 2001 From: Jacob Brydolf Date: Sat, 8 Oct 2016 01:47:08 +0200 Subject: [PATCH 28/42] persistentSettings: added restoreHeight --- wizard/WizardMain.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/wizard/WizardMain.qml b/wizard/WizardMain.qml index 7466cdf8a2..7b0b282995 100644 --- a/wizard/WizardMain.qml +++ b/wizard/WizardMain.qml @@ -137,6 +137,7 @@ Rectangle { appWindow.persistentSettings.auto_donations_amount = settings.auto_donations_amount appWindow.persistentSettings.daemon_address = settings.daemon_address appWindow.persistentSettings.testnet = settings.testnet + appWindow.persistentSettings.restoreHeight = parseInt(settings.restoreHeight) } From 38d9034470e254820c74af5b4be97c866b4a95c1 Mon Sep 17 00:00:00 2001 From: Jacob Brydolf Date: Sat, 8 Oct 2016 01:48:42 +0200 Subject: [PATCH 29/42] Wizard: added restore-height --- wizard/WizardCreateWallet.qml | 1 + wizard/WizardManageWalletUI.qml | 20 ++++++++++++++++++-- wizard/WizardRecoveryWallet.qml | 5 ++++- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/wizard/WizardCreateWallet.qml b/wizard/WizardCreateWallet.qml index 8506a8e71c..6d632cbeaa 100644 --- a/wizard/WizardCreateWallet.qml +++ b/wizard/WizardCreateWallet.qml @@ -96,5 +96,6 @@ Item { wordsTextItem.clipboardButtonVisible: true wordsTextItem.tipTextVisible: true wordsTextItem.memoTextReadOnly: true + restoreHeightVisible:false } } diff --git a/wizard/WizardManageWalletUI.qml b/wizard/WizardManageWalletUI.qml index ede68b1352..7104dc9fa1 100644 --- a/wizard/WizardManageWalletUI.qml +++ b/wizard/WizardManageWalletUI.qml @@ -29,6 +29,8 @@ import QtQuick 2.2 import moneroComponents.TranslationManager 1.0 import QtQuick.Dialogs 1.2 +import QtQuick.Layouts 1.1 +import "../components" // Reusable component for managing wallet (account name, path, private key) @@ -39,6 +41,8 @@ Item { property alias wordsTextTitle: frameHeader.text property alias walletPath: fileUrlInput.text property alias wordsTextItem : memoTextItem + property alias restoreHeight : restoreHeightItem.text + property alias restoreHeightVisible: restoreHeightItem.visible // TODO extend properties if needed @@ -112,7 +116,7 @@ Item { width: 300 height: 62 - TextInput { + TextEdit { id: accountName anchors.fill: parent horizontalAlignment: TextInput.AlignHCenter @@ -159,10 +163,22 @@ Item { anchors.topMargin: 16 } + // Restore Height + LineEdit { + id: restoreHeightItem + anchors.top: memoTextItem.bottom + width: 250 + anchors.topMargin: 20 + placeholderText: qsTr("Restore height") + Layout.alignment: Qt.AlignCenter + validator: IntValidator { + bottom:0 + } + } Row { anchors.left: parent.left anchors.right: parent.right - anchors.top: memoTextItem.bottom + anchors.top: (restoreHeightItem.visible)? restoreHeightItem.bottom : memoTextItem.bottom anchors.topMargin: 24 spacing: 16 diff --git a/wizard/WizardRecoveryWallet.qml b/wizard/WizardRecoveryWallet.qml index 00cf2440d7..7f6d87f4ae 100644 --- a/wizard/WizardRecoveryWallet.qml +++ b/wizard/WizardRecoveryWallet.qml @@ -54,12 +54,14 @@ Item { settingsObject['account_name'] = uiItem.accountNameText settingsObject['words'] = Utils.lineBreaksToSpaces(uiItem.wordsTextItem.memoText) settingsObject['wallet_path'] = uiItem.walletPath + settingsObject['restoreHeight'] = parseInt(uiItem.restoreHeight) return recoveryWallet(settingsObject) } function recoveryWallet(settingsObject) { var testnet = appWindow.persistentSettings.testnet; - var wallet = walletManager.recoveryWallet(oshelper.temporaryFilename(), settingsObject.words, testnet); + var restoreHeight = settingsObject.restoreHeight; + var wallet = walletManager.recoveryWallet(oshelper.temporaryFilename(), settingsObject.words, testnet, restoreHeight); var success = wallet.status === Wallet.Status_Ok; if (success) { settingsObject['wallet'] = wallet; @@ -80,6 +82,7 @@ Item { wordsTextItem.tipTextVisible: false wordsTextItem.memoTextReadOnly: false wordsTextItem.memoText: "" + restoreHeightVisible: true wordsTextItem.onMemoTextChanged: { checkNextButton(); } From 883762cad08d413fa109dae960aac57af6b938dd Mon Sep 17 00:00:00 2001 From: Jacob Brydolf Date: Sat, 8 Oct 2016 02:04:23 +0200 Subject: [PATCH 30/42] removed daemon-blockchain-progress rests --- main.qml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/main.qml b/main.qml index e0324e6e7f..c03d6cd892 100644 --- a/main.qml +++ b/main.qml @@ -252,10 +252,6 @@ ApplicationWindow { console.log("wallet stored after first successfull refresh") } - var dCurrentBlock = currentWallet.daemonBlockChainHeight(); - var dTargetBlock = currentWallet.daemonBlockChainTargetHeight(); - leftPanel.daemonProgress.updateProgress(dCurrentBlock,dTargetBlock); - // Store wallet after first refresh. To prevent broken wallet after a crash // TODO: Move this to libwallet? if(isNewWallet && currentWallet.blockChainHeight() > 0){ From 10c2786fca5abdc8dd963ac9994e7011c80bde3f Mon Sep 17 00:00:00 2001 From: Jacob Brydolf Date: Sat, 8 Oct 2016 02:07:13 +0200 Subject: [PATCH 31/42] added restore height to wizardFinish --- wizard/WizardFinish.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/wizard/WizardFinish.qml b/wizard/WizardFinish.qml index 48b4ae6177..890658abd7 100644 --- a/wizard/WizardFinish.qml +++ b/wizard/WizardFinish.qml @@ -47,6 +47,7 @@ Item { + qsTr("Allow background mining: ") + wizard.settings['allow_background_mining'] + "
" + qsTr("Daemon address: ") + wizard.settings['daemon_address'] + "
" + qsTr("testnet: ") + wizard.settings['testnet'] + "
" + + qsTr("Restore height: ") + wizard.settings['restoreHeight'] + "
" + translationManager.emptyString return str; } From 0ac27e13a6cf10ba76fd1f50f8443ec0eccbc019 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev Date: Sat, 8 Oct 2016 03:26:45 +0300 Subject: [PATCH 32/42] History: filter by amount --- main.cpp | 3 + pages/History.qml | 11 +++- src/libwalletqt/TransactionInfo.h | 3 +- .../TransactionHistorySortFilterModel.cpp | 66 ++++++++----------- src/model/TransactionHistorySortFilterModel.h | 17 +++-- 5 files changed, 48 insertions(+), 52 deletions(-) diff --git a/main.cpp b/main.cpp index 58ca60f84d..0e0d58e346 100644 --- a/main.cpp +++ b/main.cpp @@ -84,6 +84,9 @@ int main(int argc, char *argv[]) qmlRegisterUncreatableType("moneroComponents.TransactionHistory", 1, 0, "TransactionHistory", "TransactionHistory can't be instantiated directly"); + qmlRegisterUncreatableType("moneroComponents.TransactionInfo", 1, 0, "TransactionInfo", + "TransactionHistory can't be instantiated directly"); + qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); diff --git a/pages/History.qml b/pages/History.qml index e76fa5c961..2e45f7b6d7 100644 --- a/pages/History.qml +++ b/pages/History.qml @@ -31,6 +31,7 @@ import QtQuick 2.0 import moneroComponents.Wallet 1.0 import moneroComponents.WalletManager 1.0 import moneroComponents.TransactionHistory 1.0 +import moneroComponents.TransactionInfo 1.0 import moneroComponents.TransactionHistoryModel 1.0 import "../components" @@ -206,6 +207,10 @@ Rectangle { if (amountToLine.text.length) { model.amountToFilter = parseFloat(amountToLine.text) } + + var directionFilter = transactionsModel.get(transactionTypeDropdown.currentIndex).value + console.log("Direction filter: " + directionFilter) + model.directionFilter = directionFilter } @@ -240,9 +245,9 @@ Rectangle { ListModel { id: transactionsModel - ListElement { column1: "ALL"; column2: "" } - ListElement { column1: "SENT"; column2: "" } - ListElement { column1: "RECEIVED"; column2: "" } + ListElement { column1: "ALL"; column2: ""; value: TransactionInfo.Direction_Both } + ListElement { column1: "SENT"; column2: ""; value: TransactionInfo.Direction_Out } + ListElement { column1: "RECEIVED"; column2: ""; value: TransactionInfo.Direction_In } } diff --git a/src/libwalletqt/TransactionInfo.h b/src/libwalletqt/TransactionInfo.h index b614dfc8cd..f30f42fa1e 100644 --- a/src/libwalletqt/TransactionInfo.h +++ b/src/libwalletqt/TransactionInfo.h @@ -24,7 +24,8 @@ class TransactionInfo : public QObject public: enum Direction { Direction_In = Bitmonero::TransactionInfo::Direction_In, - Direction_Out = Bitmonero::TransactionInfo::Direction_Out + Direction_Out = Bitmonero::TransactionInfo::Direction_Out, + Direction_Both // invalid direction value, used for filtering }; Q_ENUM(Direction) diff --git a/src/model/TransactionHistorySortFilterModel.cpp b/src/model/TransactionHistorySortFilterModel.cpp index d06d44bff7..6d6a2b447a 100644 --- a/src/model/TransactionHistorySortFilterModel.cpp +++ b/src/model/TransactionHistorySortFilterModel.cpp @@ -112,6 +112,20 @@ void TransactionHistorySortFilterModel::setAmountToFilter(double value) } } +int TransactionHistorySortFilterModel::directionFilter() const +{ + return m_filterValues.value(TransactionHistoryModel::TransactionDirectionRole).value(); +} + +void TransactionHistorySortFilterModel::setDirectionFilter(int value) +{ + if (value != directionFilter()) { + m_filterValues[TransactionHistoryModel::TransactionDirectionRole] = QVariant::fromValue(value); + emit directionFilterChanged(); + invalidateFilter(); + } +} + void TransactionHistorySortFilterModel::sort(int column, Qt::SortOrder order) { @@ -150,6 +164,7 @@ bool TransactionHistorySortFilterModel::filterAcceptsRow(int source_row, const Q { QDateTime from = QDateTime(dateFromFilter()); QDateTime to = QDateTime(dateToFilter()); + to = to.addDays(1); // including upperbound QDateTime timestamp = data.toDateTime(); bool matchFrom = from.isNull() || timestamp.isNull() || timestamp >= from; bool matchTo = to.isNull() || timestamp.isNull() || timestamp <= to; @@ -162,17 +177,26 @@ bool TransactionHistorySortFilterModel::filterAcceptsRow(int source_row, const Q double to = amountToFilter(); double amount = data.toDouble(); - bool matchFrom = from < 0 || amount >= from; - bool matchTo = to < 0 || amount <= to; + bool matchFrom = from <= 0 || amount >= from; + bool matchTo = to <= 0 || amount <= to; result = matchFrom && matchTo; } break; + case TransactionHistoryModel::TransactionDirectionRole: + result = directionFilter() == TransactionInfo::Direction_Both ? true + : data.toInt() == directionFilter(); + + + break; + default: break; } - if (!result) // stop the loop once filter doesn't match + + if (!result) { // stop the loop once filter doesn't match break; + } } } @@ -183,39 +207,3 @@ bool TransactionHistorySortFilterModel::lessThan(const QModelIndex &source_left, { 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; -} - -QDate TransactionHistorySortFilterModel::dateFromToFilter(TransactionHistorySortFilterModel::ScopeIndex index) const -{ - int role = TransactionHistoryModel::TransactionTimeStampRole; - if (!m_filterValues.contains(role)) { - return QDate(); - } - return m_filterValues.value(role).toList().at(index).toDate(); -} - -void TransactionHistorySortFilterModel::setDateFromToFilter(TransactionHistorySortFilterModel::ScopeIndex index, const QDate &value) -{ - QVariantList scopeFilter; - int role = TransactionHistoryModel::TransactionTimeStampRole; - if (m_filterValues.contains(role)) { - scopeFilter = m_filterValues.value(role).toList(); - } - while (scopeFilter.size() < 2) { - scopeFilter.append(QDate()); - } - scopeFilter[index] = QVariant::fromValue(value); - m_filterValues[role] = scopeFilter; -} - - - diff --git a/src/model/TransactionHistorySortFilterModel.h b/src/model/TransactionHistorySortFilterModel.h index 43c46a7b26..1b5c2fce17 100644 --- a/src/model/TransactionHistorySortFilterModel.h +++ b/src/model/TransactionHistorySortFilterModel.h @@ -1,12 +1,14 @@ #ifndef TRANSACTIONHISTORYSORTFILTERMODEL_H #define TRANSACTIONHISTORYSORTFILTERMODEL_H +#include "TransactionInfo.h" #include #include #include #include + class TransactionHistory; class TransactionHistorySortFilterModel: public QSortFilterProxyModel @@ -17,6 +19,8 @@ class TransactionHistorySortFilterModel: public QSortFilterProxyModel Q_PROPERTY(QDate dateToFilter READ dateToFilter WRITE setDateToFilter NOTIFY dateToFilterChanged) Q_PROPERTY(double amountFromFilter READ amountFromFilter WRITE setAmountFromFilter NOTIFY amountFromFilterChanged) Q_PROPERTY(double amountToFilter READ amountToFilter WRITE setAmountToFilter NOTIFY amountToFilterChanged) + Q_PROPERTY(int directionFilter READ directionFilter WRITE setDirectionFilter NOTIFY directionFilterChanged) + Q_PROPERTY(TransactionHistory * transactionHistory READ transactionHistory) public: @@ -41,6 +45,9 @@ class TransactionHistorySortFilterModel: public QSortFilterProxyModel double amountToFilter() const; void setAmountToFilter(double value); + //! filtering by direction + int directionFilter() const; + void setDirectionFilter(int value); Q_INVOKABLE void sort(int column, Qt::SortOrder order); TransactionHistory * transactionHistory() const; @@ -51,6 +58,7 @@ class TransactionHistorySortFilterModel: public QSortFilterProxyModel void dateToFilterChanged(); void amountFromFilterChanged(); void amountToFilterChanged(); + void directionFilterChanged(); protected: // QSortFilterProxyModel overrides @@ -64,15 +72,6 @@ class TransactionHistorySortFilterModel: public QSortFilterProxyModel To = 1 }; - QVariant filterValue(int role); - void setFilterValue(int role, const QVariant &filterValue); - QDate dateFromToFilter(ScopeIndex index) const; - void setDateFromToFilter(ScopeIndex index, const QDate &value); -// double amountFromToFilter(ScopeIndex index) const; -// void setAmountFromToFilter(ScopeIndex index, double value); - - - private: QMap m_filterValues; }; From 60b2d9003342528d6906ae5bf61e38439ce69d97 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev Date: Sat, 8 Oct 2016 03:54:35 +0300 Subject: [PATCH 33/42] History: display "fee" for sent transactions --- components/HistoryTable.qml | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/components/HistoryTable.qml b/components/HistoryTable.qml index 0cca11487c..f08ce8d283 100644 --- a/components/HistoryTable.qml +++ b/components/HistoryTable.qml @@ -252,7 +252,33 @@ ListView { font.pixelSize: 18 font.letterSpacing: -1 color: isOut ? "#FF4F41" : "#36B05B" - text: displayAmount + text: displayAmount + } + } + } + + // -- "Fee column + Column { + anchors.top: parent.top + width: 148 + visible: isOut + Text { + anchors.left: parent.left + font.family: "Arial" + font.pixelSize: 12 + color: "#545454" + text: qsTr("Fee") + translationManager.emptyString + } + + Row { + spacing: 2 + Text { + anchors.bottom: parent.bottom + font.family: "Arial" + font.pixelSize: 18 + font.letterSpacing: -1 + color: isOut ? "#FF4F41" : "#36B05B" + text: fee } } } From a032c841b4fa750a877a81af2b15b67e8b5c3afc Mon Sep 17 00:00:00 2001 From: Ilya Kitaev Date: Sat, 8 Oct 2016 04:30:55 +0300 Subject: [PATCH 34/42] History: fee color --- components/HistoryTable.qml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/components/HistoryTable.qml b/components/HistoryTable.qml index f08ce8d283..867fdedfa5 100644 --- a/components/HistoryTable.qml +++ b/components/HistoryTable.qml @@ -277,7 +277,7 @@ ListView { font.family: "Arial" font.pixelSize: 18 font.letterSpacing: -1 - color: isOut ? "#FF4F41" : "#36B05B" + color: "#FF4F41" text: fee } } @@ -286,7 +286,9 @@ ListView { - + /* + // Transaction dropdown menu. + // Disable for now until AddressBook implemented TableDropdown { id: dropdown anchors.right: parent.right @@ -314,6 +316,7 @@ ListView { height: 1 color: "#DBDBDB" } + */ } ListModel { From eafcf71382ad26e6e4be959405ae0701bc1ce0c9 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev Date: Sun, 9 Oct 2016 00:50:35 +0300 Subject: [PATCH 35/42] Minimized aka basic mode --- BasicPanel.qml | 2 + MiddlePanel.qml | 165 ++++++++++++++++++++++++++++++++++++++++------ main.qml | 44 ++++++------- pages/History.qml | 1 - 4 files changed, 167 insertions(+), 45 deletions(-) diff --git a/BasicPanel.qml b/BasicPanel.qml index 07aeb0803e..12a257bf5e 100644 --- a/BasicPanel.qml +++ b/BasicPanel.qml @@ -31,6 +31,8 @@ import QtGraphicalEffects 1.0 import "components" import "pages" +// mbg033 @ 2016-10-08: Not used anymore, to be deleted + Rectangle { id: root width: 470 diff --git a/MiddlePanel.qml b/MiddlePanel.qml index 6ce1c2424d..97dcf56c28 100644 --- a/MiddlePanel.qml +++ b/MiddlePanel.qml @@ -29,17 +29,24 @@ import QtQuick 2.2 import QtQml 2.0 import QtQuick.Controls 2.0 +import QtQuick.Layouts 1.1 import QtGraphicalEffects 1.0 import "pages" Rectangle { id: root + + property Item currentView + property bool basicMode : false property Transfer transferView: Transfer { } property Receive receiveView: Receive { } property History historyView: History { } property Settings settingsView: Settings { } - property Item currentView + signal paymentClicked(string address, string paymentId, double amount, int mixinCount, int priority) + signal generatePaymentIdInvoked() + + color: "#F0EEEE" onCurrentViewChanged: { if (currentView) { @@ -52,9 +59,7 @@ Rectangle { } } - color: "#F0EEEE" - signal paymentClicked(string address, string paymentId, double amount, int mixinCount, int priority) - signal generatePaymentIdInvoked() + // states: [ // State { @@ -107,11 +112,15 @@ Rectangle { } ] + + // color stripe at the top Row { id: styledRow + height: 4 + anchors.top: parent.top anchors.left: parent.left anchors.right: parent.right - anchors.top: parent.top + Rectangle { height: 4; width: parent.width / 5; color: "#FFE00A" } Rectangle { height: 4; width: parent.width / 5; color: "#6B0072" } @@ -120,24 +129,127 @@ Rectangle { Rectangle { height: 4; width: parent.width / 5; color: "#FF4F41" } } - StackView { - id: stackView - initialItem: transferView + ColumnLayout { anchors.fill: parent - anchors.margins: 4 - clip: true // otherwise animation will affect left panel - } + anchors.margins: 2 + anchors.topMargin: 30 + spacing: 0 - /* connect "payment" click */ - Connections { - ignoreUnknownSignals: false - target: transferView - onPaymentClicked : { - console.log("MiddlePanel: paymentClicked") - paymentClicked(address, paymentId, amount, mixinCount, priority) + + // BasicPanel header + Rectangle { + id: header + anchors.leftMargin: 1 + anchors.rightMargin: 1 + Layout.fillWidth: true + Layout.preferredHeight: 64 + color: "#FFFFFF" + visible: false + + Image { + id: logo + anchors.verticalCenter: parent.verticalCenter + anchors.verticalCenterOffset: -5 + anchors.left: parent.left + anchors.leftMargin: 20 + source: "images/moneroLogo2.png" + } + + Grid { + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.right + width: 256 + columns: 3 + + Text { + + width: 116 + height: 20 + font.family: "Arial" + font.pixelSize: 12 + font.letterSpacing: -1 + elide: Text.ElideRight + horizontalAlignment: Text.AlignLeft + verticalAlignment: Text.AlignBottom + color: "#535353" + text: qsTr("Locked Balance:") + } + + Text { + id: balanceText + width: 110 + height: 20 + font.family: "Arial" + font.pixelSize: 18 + font.letterSpacing: -1 + elide: Text.ElideRight + horizontalAlignment: Text.AlignLeft + verticalAlignment: Text.AlignBottom + color: "#000000" + text: qsTr("78.9239845") + } + + Item { + height: 20 + width: 20 + + Image { + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + source: "images/lockIcon.png" + } + } + + Text { + width: 116 + height: 20 + font.family: "Arial" + font.pixelSize: 12 + font.letterSpacing: -1 + elide: Text.ElideRight + horizontalAlignment: Text.AlignLeft + verticalAlignment: Text.AlignBottom + color: "#535353" + text: qsTr("Available Balance:") + } + + Text { + id: availableBalanceText + width: 110 + height: 20 + font.family: "Arial" + font.pixelSize: 14 + font.letterSpacing: -1 + elide: Text.ElideRight + horizontalAlignment: Text.AlignLeft + verticalAlignment: Text.AlignBottom + color: "#000000" + text: qsTr("2324.9239845") + } + } + + Rectangle { + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + height: 1 + color: "#DBDBDB" + } } - } + // Views container + StackView { + id: stackView + initialItem: transferView + anchors.topMargin: 30 + Layout.fillWidth: true + Layout.fillHeight: true + anchors.top: styledRow.bottom + anchors.margins: 4 + clip: true // otherwise animation will affect left panel + } + } + // border Rectangle { anchors.top: styledRow.bottom anchors.bottom: parent.bottom @@ -160,12 +272,25 @@ Rectangle { anchors.bottom: parent.bottom height: 1 color: "#DBDBDB" + } - // indicate disabled state + + // indicates disabled state Desaturate { anchors.fill: parent source: parent desaturation: root.enabled ? 0.0 : 1.0 } + + + /* connect "payment" click */ + Connections { + ignoreUnknownSignals: false + target: transferView + onPaymentClicked : { + console.log("MiddlePanel: paymentClicked") + paymentClicked(address, paymentId, amount, mixinCount, priority) + } + } } diff --git a/main.qml b/main.qml index c03d6cd892..ee14a167ac 100644 --- a/main.qml +++ b/main.qml @@ -230,9 +230,9 @@ ApplicationWindow { function onWalletUpdate() { console.log(">>> wallet updated") - basicPanel.unlockedBalanceText = leftPanel.unlockedBalanceText = - walletManager.displayAmount(currentWallet.unlockedBalance); - basicPanel.balanceText = leftPanel.balanceText = walletManager.displayAmount(currentWallet.balance); +// basicPanel.unlockedBalanceText = leftPanel.unlockedBalanceText = +// walletManager.displayAmount(currentWallet.unlockedBalance); +// basicPanel.balanceText = leftPanel.balanceText = walletManager.displayAmount(currentWallet.balance); } function onWalletRefresh() { @@ -396,7 +396,7 @@ ApplicationWindow { middlePanel.enabled = enable; leftPanel.enabled = enable; rightPanel.enabled = enable; - basicPanel.enabled = enable; + // basicPanel.enabled = enable; } function showProcessingSplash(message) { @@ -573,7 +573,7 @@ ApplicationWindow { MiddlePanel { id: middlePanel anchors.bottom: parent.bottom - anchors.left: leftPanel.right + anchors.left: leftPanel.visible ? leftPanel.right : parent.left anchors.right: rightPanel.left height: parent.height state: "Transfer" @@ -585,16 +585,6 @@ ApplicationWindow { visible: false } - BasicPanel { - id: basicPanel - x: 0 - anchors.bottom: parent.bottom - anchors.top: parent.top - anchors.left: parent.left - anchors.right: parent.right - visible: false - } - MouseArea { id: frameArea property bool blocked: false @@ -650,25 +640,26 @@ ApplicationWindow { duration: 200 } PropertyAction { - targets: [leftPanel, middlePanel, rightPanel] + targets: [leftPanel, rightPanel] properties: "visible" value: false } PropertyAction { - target: basicPanel - properties: "visible" + target: middlePanel + properties: "basicMode" value: true } + NumberAnimation { target: appWindow properties: "height" - to: basicPanel.height + to: middlePanel.height easing.type: Easing.InCubic duration: 200 } onStopped: { - middlePanel.visible = false + // middlePanel.visible = false rightPanel.visible = false leftPanel.visible = false } @@ -684,8 +675,8 @@ ApplicationWindow { duration: 200 } PropertyAction { - target: basicPanel - properties: "visible" + target: middlePanel + properties: "basicMode" value: false } PropertyAction { @@ -778,8 +769,13 @@ ApplicationWindow { anchors.left: parent.left anchors.right: parent.right onGoToBasicVersion: { - if(yes) goToBasicAnimation.start() - else goToProAnimation.start() + if (yes) { + // basicPanel.currentView = middlePanel.currentView + goToBasicAnimation.start() + } else { + // middlePanel.currentView = basicPanel.currentView + goToProAnimation.start() + } } MouseArea { diff --git a/pages/History.qml b/pages/History.qml index 2e45f7b6d7..74dcf14017 100644 --- a/pages/History.qml +++ b/pages/History.qml @@ -41,7 +41,6 @@ Rectangle { property var model color: "#F0EEEE" - onModelChanged: { if (typeof model !== 'undefined') { // setup date filter scope according to real transactions From 7ed623e6d9c8eabcc3caefb381fea54d7c50b858 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev Date: Sun, 9 Oct 2016 01:32:03 +0300 Subject: [PATCH 36/42] Basic mode: updating balance properly --- MiddlePanel.qml | 14 +++++++++----- main.qml | 5 ++--- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/MiddlePanel.qml b/MiddlePanel.qml index 97dcf56c28..b60cb8388c 100644 --- a/MiddlePanel.qml +++ b/MiddlePanel.qml @@ -43,6 +43,10 @@ Rectangle { property History historyView: History { } property Settings settingsView: Settings { } + property string balanceText + property string unlockedBalanceText + + signal paymentClicked(string address, string paymentId, double amount, int mixinCount, int priority) signal generatePaymentIdInvoked() @@ -144,7 +148,7 @@ Rectangle { Layout.fillWidth: true Layout.preferredHeight: 64 color: "#FFFFFF" - visible: false + visible: basicMode Image { id: logo @@ -172,7 +176,7 @@ Rectangle { horizontalAlignment: Text.AlignLeft verticalAlignment: Text.AlignBottom color: "#535353" - text: qsTr("Locked Balance:") + text: qsTr("Balance:") } Text { @@ -186,7 +190,7 @@ Rectangle { horizontalAlignment: Text.AlignLeft verticalAlignment: Text.AlignBottom color: "#000000" - text: qsTr("78.9239845") + text: root.balanceText } Item { @@ -210,7 +214,7 @@ Rectangle { horizontalAlignment: Text.AlignLeft verticalAlignment: Text.AlignBottom color: "#535353" - text: qsTr("Available Balance:") + text: qsTr("Unlocked Balance:") } Text { @@ -224,7 +228,7 @@ Rectangle { horizontalAlignment: Text.AlignLeft verticalAlignment: Text.AlignBottom color: "#000000" - text: qsTr("2324.9239845") + text: root.unlockedBalanceText } } diff --git a/main.qml b/main.qml index ee14a167ac..6cf753e837 100644 --- a/main.qml +++ b/main.qml @@ -230,9 +230,8 @@ ApplicationWindow { function onWalletUpdate() { console.log(">>> wallet updated") -// basicPanel.unlockedBalanceText = leftPanel.unlockedBalanceText = -// walletManager.displayAmount(currentWallet.unlockedBalance); -// basicPanel.balanceText = leftPanel.balanceText = walletManager.displayAmount(currentWallet.balance); + middlePanel.unlockedBalanceText = leftPanel.unlockedBalanceText = walletManager.displayAmount(currentWallet.unlockedBalance); + middlePanel.balanceText = leftPanel.balanceText = walletManager.displayAmount(currentWallet.balance); } function onWalletRefresh() { From da552a012d5a2188a788c7ba9cc6949b2d299ccf Mon Sep 17 00:00:00 2001 From: Ilya Kitaev Date: Sun, 9 Oct 2016 01:40:13 +0300 Subject: [PATCH 37/42] History: Fixed filter collapse --- pages/History.qml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pages/History.qml b/pages/History.qml index 74dcf14017..4c2a0dec2e 100644 --- a/pages/History.qml +++ b/pages/History.qml @@ -326,8 +326,11 @@ Rectangle { anchors.fill: parent onClicked: { parent.expanded = !parent.expanded - if(checkBox.checked) tableRect.height = Qt.binding(function(){ return parent.expanded ? tableRect.expandedHeight : tableRect.collapsedHeight }) - else tableRect.height = Qt.binding(function(){ return parent.expanded ? tableRect.expandedHeight : tableRect.middleHeight }) + if (advancedFilteringCheckBox.checked) { + tableRect.height = Qt.binding(function() { return parent.expanded ? tableRect.expandedHeight : tableRect.collapsedHeight }) + } else { + tableRect.height = Qt.binding(function() { return parent.expanded ? tableRect.expandedHeight : tableRect.middleHeight }) + } } } } From 4f4cc9c8e860de0a84ff7296c0b5358ed030e0e4 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev Date: Sun, 9 Oct 2016 01:54:15 +0300 Subject: [PATCH 38/42] Settings page: small renaming and formatting --- pages/Settings.qml | 182 ++++++++++++++++++++++++++------------------- 1 file changed, 105 insertions(+), 77 deletions(-) diff --git a/pages/Settings.qml b/pages/Settings.qml index 629d06ade6..0f73ae32de 100644 --- a/pages/Settings.qml +++ b/pages/Settings.qml @@ -1,21 +1,21 @@ // Copyright (c) 2014-2015, The Monero Project -// +// // All rights reserved. -// +// // Redistribution and use in source and binary forms, with or without modification, are // permitted provided that the following conditions are met: -// +// // 1. Redistributions of source code must retain the above copyright notice, this list of // conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright notice, this list // of conditions and the following disclaimer in the documentation and/or other // materials provided with the distribution. -// +// // 3. Neither the name of the copyright holder nor the names of its contributors may be // used to endorse or promote products derived from this software without specific // prior written permission. -// +// // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL @@ -34,10 +34,8 @@ import QtQuick.Dialogs 1.2 import "../components" - import moneroComponents.Clipboard 1.0 - Rectangle { property var daemonAddress @@ -46,16 +44,17 @@ Rectangle { Clipboard { id: clipboard } - function initSettings(){ + function initSettings() { // Mnemonic seed settings memoTextInput.text = qsTr("Click button to show seed") + translationManager.emptyString - showSeedbtn.visible = true + showSeedButton.visible = true // Daemon settings + daemonAddress = persistentSettings.daemon_address.split(":"); - console.log("address" + persistentSettings.daemon_address) + console.log("address: " + persistentSettings.daemon_address) // try connecting to daemon var connectedToDaemon = currentWallet.connectToDaemon(); @@ -68,42 +67,65 @@ Rectangle { } + + PasswordDialog { + id: settingsPasswordDialog + standardButtons: StandardButton.Ok + StandardButton.Cancel + onAccepted: { + if(appWindow.password == settingsPasswordDialog.password){ + memoTextInput.text = currentWallet.seed + showSeedButton.visible = false + } + + } + onRejected: { + + } + onDiscard: { + + } + } + + ColumnLayout { id: mainLayout anchors.margins: 40 anchors.left: parent.left anchors.top: parent.top anchors.right: parent.right + spacing: 10 - spacing: 20 - property int labelWidth: 120 - property int editWidth: 400 - property int lineEditFontSize: 12 - RowLayout { - id: paymentIdRow - Label { - id: seedLabel - color: "#4A4949" - text: qsTr("Mnemonic seed") + translationManager.emptyString - } + Label { + id: seedLabel + color: "#4A4949" + fontSize: 16 + text: qsTr("Mnemonic seed: ") + translationManager.emptyString + Layout.preferredWidth: 100 + Layout.alignment: Qt.AlignLeft + } - TextArea { - id: memoTextInput - textMargin: 8 - font.family: "Arial" - font.pointSize: 15 - wrapMode: TextEdit.WordWrap - readOnly: true - selectByMouse: true - height: 300 - width: 500 - } - Image { + TextArea { + id: memoTextInput + textMargin: 6 + font.family: "Arial" + font.pointSize: 14 + wrapMode: TextEdit.WordWrap + readOnly: true + selectByMouse: true + + Layout.fillWidth: true + Layout.preferredHeight: 100 + Layout.alignment: Qt.AlignHCenter + + text: qsTr("Click button to show seed") + translationManager.emptyString + + Image { id : clipboardButton anchors.right: memoTextInput.right anchors.bottom: memoTextInput.bottom source: "qrc:///images/greyTriangle.png" + Image { anchors.centerIn: parent source: "qrc:///images/copyToClipboard.png" @@ -114,85 +136,89 @@ Rectangle { onClicked: clipboard.setText(memoTextInput.text) } } + } + RowLayout { + Layout.fillWidth: true + Text { + id: wordsTipText + font.family: "Arial" + font.pointSize: 12 + color: "#4A4646" + Layout.fillWidth: true + wrapMode: Text.WordWrap + text: qsTr("It is very important to write it down as this is the only backup you will need for your wallet.") + + translationManager.emptyString + } StandardButton { - id: showSeedbtn - width: 80 + + id: showSeedButton + fontSize: 14 shadowReleasedColor: "#FF4304" shadowPressedColor: "#B32D00" releasedColor: "#FF6C3C" pressedColor: "#FF4304" text: qsTr("Show seed") + Layout.alignment: Qt.AlignRight + Layout.preferredWidth: 100 onClicked: { settingsPasswordDialog.open(); } } + } - PasswordDialog { - id: settingsPasswordDialog - standardButtons: StandardButton.Ok + StandardButton.Cancel - onAccepted: { - if(appWindow.password == settingsPasswordDialog.password){ - memoTextInput.text = currentWallet.seed - showSeedbtn.visible = false - } - } - onRejected: { - - } - onDiscard: { - } - } - - } - RowLayout { - id: wordsTipTextRow - - Text { - id: wordsTipText - font.family: "Arial" - font.pixelSize: 15 - color: "#4A4646" - wrapMode: Text.WordWrap - text: qsTr("It is very important to write it down as this is the only backup you will need for your wallet.") - + translationManager.emptyString - } + Rectangle { + Layout.fillWidth: true + height: 1 + color: "#DEDEDE" } - RowLayout { id: daemonAddrRow + Layout.fillWidth: true + Layout.preferredHeight: 40 + Layout.topMargin: 40 + spacing: 10 + Label { id: daemonAddrLabel + + Layout.fillWidth: true color: "#4A4949" text: qsTr("Daemon adress") + translationManager.emptyString + fontSize: 16 } - LineEdit { id: daemonAddr - width: 180 - text: (daemonAddress != undefined)? daemonAddress[0] : "" + Layout.preferredWidth: 200 + Layout.fillWidth: true + text: (daemonAddress !== undefined) ? daemonAddress[0] : "" placeholderText: qsTr("Hostname / IP") } + LineEdit { id: daemonPort - width: 150 - text: (daemonAddress != undefined)? daemonAddress[1] : "" + Layout.preferredWidth: 100 + Layout.fillWidth: true + text: (daemonAddress !== undefined) ? daemonAddress[1] : "" placeholderText: qsTr("Port") } StandardButton { id: daemonAddrSave - anchors.left: daemonPort.right - anchors.leftMargin: 30 + + Layout.fillWidth: false + + Layout.leftMargin: 30 + Layout.minimumWidth: 100 width: 60 text: qsTr("Save") + translationManager.emptyString shadowReleasedColor: "#FF4304" @@ -213,8 +239,12 @@ Rectangle { } + RowLayout { id: daemonStatusRow + + Layout.fillWidth: true + Text { id: daemonStatusText font.family: "Arial" @@ -242,6 +272,7 @@ Rectangle { // } // } } + } @@ -251,8 +282,5 @@ Rectangle { initSettings(); } -} - - - +} From d67071a7a488a638e580489305c0b9df4dd9b607 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev Date: Sun, 9 Oct 2016 02:23:57 +0300 Subject: [PATCH 39/42] Settings page: layout items vertically --- MiddlePanel.qml | 57 +++++++++++++++++++++++----------------------- pages/Settings.qml | 16 ++++++++----- 2 files changed, 38 insertions(+), 35 deletions(-) diff --git a/MiddlePanel.qml b/MiddlePanel.qml index b60cb8388c..9160a359cc 100644 --- a/MiddlePanel.qml +++ b/MiddlePanel.qml @@ -38,14 +38,14 @@ Rectangle { property Item currentView property bool basicMode : false + property string balanceText + property string unlockedBalanceText + property Transfer transferView: Transfer { } property Receive receiveView: Receive { } property History historyView: History { } property Settings settingsView: Settings { } - property string balanceText - property string unlockedBalanceText - signal paymentClicked(string address, string paymentId, double amount, int mixinCount, int priority) signal generatePaymentIdInvoked() @@ -64,31 +64,31 @@ Rectangle { } - -// states: [ -// State { -// name: "Dashboard" -// PropertyChanges { target: loader; source: "pages/Dashboard.qml" } -// }, State { -// name: "History" -// PropertyChanges { target: loader; source: "pages/History.qml" } -// }, State { -// name: "Transfer" -// PropertyChanges { target: loader; source: "pages/Transfer.qml" } -// }, State { -// name: "Receive" -// PropertyChanges { target: loader; source: "pages/Receive.qml" } -// }, State { -// name: "AddressBook" -// PropertyChanges { target: loader; source: "pages/AddressBook.qml" } -// }, State { -// name: "Settings" -// PropertyChanges { target: loader; source: "pages/Settings.qml" } -// }, State { -// name: "Mining" -// PropertyChanges { target: loader; source: "pages/Mining.qml" } -// } -// ] + // XXX: just for memo, to be removed + // states: [ + // State { + // name: "Dashboard" + // PropertyChanges { target: loader; source: "pages/Dashboard.qml" } + // }, State { + // name: "History" + // PropertyChanges { target: loader; source: "pages/History.qml" } + // }, State { + // name: "Transfer" + // PropertyChanges { target: loader; source: "pages/Transfer.qml" } + // }, State { + // name: "Receive" + // PropertyChanges { target: loader; source: "pages/Receive.qml" } + // }, State { + // name: "AddressBook" + // PropertyChanges { target: loader; source: "pages/AddressBook.qml" } + // }, State { + // name: "Settings" + // PropertyChanges { target: loader; source: "pages/Settings.qml" } + // }, State { + // name: "Mining" + // PropertyChanges { target: loader; source: "pages/Mining.qml" } + // } + // ] states: [ State { @@ -116,7 +116,6 @@ Rectangle { } ] - // color stripe at the top Row { id: styledRow diff --git a/pages/Settings.qml b/pages/Settings.qml index 0f73ae32de..d46186af51 100644 --- a/pages/Settings.qml +++ b/pages/Settings.qml @@ -1,21 +1,21 @@ // Copyright (c) 2014-2015, The Monero Project -// +// // All rights reserved. -// +// // Redistribution and use in source and binary forms, with or without modification, are // permitted provided that the following conditions are met: -// +// // 1. Redistributions of source code must retain the above copyright notice, this list of // conditions and the following disclaimer. -// +// // 2. Redistributions in binary form must reproduce the above copyright notice, this list // of conditions and the following disclaimer in the documentation and/or other // materials provided with the distribution. -// +// // 3. Neither the name of the copyright holder nor the names of its contributors may be // used to endorse or promote products derived from this software without specific // prior written permission. -// +// // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL @@ -284,3 +284,7 @@ Rectangle { } + + + + From 54b22d21a8a151fd8e4e1a32a9dcbb090a319995 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev Date: Sun, 9 Oct 2016 21:49:07 +0300 Subject: [PATCH 40/42] Wizard: finish page: restore height hidden if not set --- wizard/WizardFinish.qml | 2 +- wizard/WizardMain.qml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/wizard/WizardFinish.qml b/wizard/WizardFinish.qml index 890658abd7..7c44b7bc5d 100644 --- a/wizard/WizardFinish.qml +++ b/wizard/WizardFinish.qml @@ -47,7 +47,7 @@ Item { + qsTr("Allow background mining: ") + wizard.settings['allow_background_mining'] + "
" + qsTr("Daemon address: ") + wizard.settings['daemon_address'] + "
" + qsTr("testnet: ") + wizard.settings['testnet'] + "
" - + qsTr("Restore height: ") + wizard.settings['restoreHeight'] + "
" + + (wizard.settings['restore_height'] === undefined ? "" : qsTr("Restore height: ") + wizard.settings['restore_height']) + "
" + translationManager.emptyString return str; } diff --git a/wizard/WizardMain.qml b/wizard/WizardMain.qml index 7b0b282995..3168733b18 100644 --- a/wizard/WizardMain.qml +++ b/wizard/WizardMain.qml @@ -137,7 +137,7 @@ Rectangle { appWindow.persistentSettings.auto_donations_amount = settings.auto_donations_amount appWindow.persistentSettings.daemon_address = settings.daemon_address appWindow.persistentSettings.testnet = settings.testnet - appWindow.persistentSettings.restoreHeight = parseInt(settings.restoreHeight) + appWindow.persistentSettings.restore_height = parseInt(settings.restore_height) } From be135e39cc4c1fc9981b8e9c1dbae9d056f8f769 Mon Sep 17 00:00:00 2001 From: Ilya Kitaev Date: Sun, 9 Oct 2016 21:49:56 +0300 Subject: [PATCH 41/42] Processing splash formatting improved --- components/ProcessingSplash.qml | 7 +++++++ get_libwallet_api.sh | 8 ++++---- main.qml | 4 ++-- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/components/ProcessingSplash.qml b/components/ProcessingSplash.qml index 297631eca4..84218f8802 100644 --- a/components/ProcessingSplash.qml +++ b/components/ProcessingSplash.qml @@ -43,8 +43,13 @@ Window { opacity: 0.7 ColumnLayout { + id: rootLayout anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + anchors.right: parent.right + anchors.leftMargin: 30 + anchors.rightMargin: 30 BusyIndicator { running: parent.visible @@ -59,6 +64,7 @@ Window { } horizontalAlignment: Text.AlignHCenter Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter + Layout.fillWidth: true } @@ -69,6 +75,7 @@ Window { } horizontalAlignment: Text.AlignHCenter Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter + Layout.fillWidth: true } } } diff --git a/get_libwallet_api.sh b/get_libwallet_api.sh index d46b9910ae..fbba689ac8 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 # Buidling "debug" build optionally BUILD_TYPE=$1 if [ -z $BUILD_TYPE ]; then diff --git a/main.qml b/main.qml index 6cf753e837..9d1bf326ba 100644 --- a/main.qml +++ b/main.qml @@ -282,7 +282,7 @@ ApplicationWindow { var locale = Qt.locale() var currHeightString = currHeight.toLocaleString(locale,"f",0) var targetHeightString = currentWallet.daemonBlockChainHeight().toLocaleString(locale,"f",0) - var progressText = qsTr("Synchronizing blocks %1/%2").arg(currHeightString).arg(targetHeightString); + var progressText = qsTr("Synchronizing blocks %1 / %2").arg(currHeightString).arg(targetHeightString); console.log("Progress text: " + progressText); splash.heightProgressText = progressText } @@ -498,7 +498,7 @@ ApplicationWindow { ProcessingSplash { id: splash - width: appWindow.width / 2 + width: appWindow.width / 1.5 height: appWindow.height / 2 x: (appWindow.width - width) / 2 + appWindow.x y: (appWindow.height - height) / 2 + appWindow.y From b1454c6a1366ccf044d9ff92ac1aa95d2249f06b Mon Sep 17 00:00:00 2001 From: Ilya Kitaev Date: Mon, 10 Oct 2016 01:08:35 +0300 Subject: [PATCH 42/42] removed duplicated-by-mistake code --- main.qml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/main.qml b/main.qml index 9d1bf326ba..ac45ed2008 100644 --- a/main.qml +++ b/main.qml @@ -251,14 +251,6 @@ ApplicationWindow { console.log("wallet stored after first successfull refresh") } - // Store wallet after first refresh. To prevent broken wallet after a crash - // TODO: Move this to libwallet? - if(isNewWallet && currentWallet.blockChainHeight() > 0){ - currentWallet.store(persistentSettings.wallet_path) - isNewWallet = false - console.log("wallet stored after first successfull refresh") - } - // initialize transaction history once wallet is initializef first time; if (!walletInitialized) { currentWallet.history.refresh()