add account support

Co-authored-by: kenshi84 <kenshi84@protonmail.ch>
This commit is contained in:
selsta 2019-01-14 13:25:59 +01:00
parent 9689fff957
commit bd809abc52
No known key found for this signature in database
GPG key ID: 2EA0A99A8B07AE5E
17 changed files with 654 additions and 7 deletions

View file

@ -61,6 +61,7 @@ Rectangle {
signal signClicked() signal signClicked()
signal keysClicked() signal keysClicked()
signal merchantClicked() signal merchantClicked()
signal accountClicked()
function selectItem(pos) { function selectItem(pos) {
menuColumn.previousButton.checked = false menuColumn.previousButton.checked = false
@ -76,7 +77,7 @@ Rectangle {
else if(pos === "Settings") menuColumn.previousButton = settingsButton else if(pos === "Settings") menuColumn.previousButton = settingsButton
else if(pos === "Advanced") menuColumn.previousButton = advancedButton else if(pos === "Advanced") menuColumn.previousButton = advancedButton
else if(pos === "Keys") menuColumn.previousButton = keysButton else if(pos === "Keys") menuColumn.previousButton = keysButton
else if(pos === "Account") menuColumn.previousButton = accountButton
menuColumn.previousButton.checked = true menuColumn.previousButton.checked = true
} }
@ -285,6 +286,8 @@ Rectangle {
anchors.leftMargin: 20 anchors.leftMargin: 20
anchors.top: parent.top anchors.top: parent.top
anchors.topMargin: 60 anchors.topMargin: 60
elide: Text.ElideRight
textWidth: 238
} }
Item { //separator Item { //separator
anchors.left: parent.left anchors.left: parent.left
@ -331,6 +334,30 @@ Rectangle {
height: 1 height: 1
} }
// ------------- Account tab ---------------
MoneroComponents.MenuButton {
id: accountButton
anchors.left: parent.left
anchors.right: parent.right
text: qsTr("Account") + translationManager.emptyString
symbol: qsTr("T") + translationManager.emptyString
dotColor: "#44AAFF"
onClicked: {
parent.previousButton.checked = false
parent.previousButton = accountButton
panel.accountClicked()
}
}
Rectangle {
visible: accountButton.present
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: 16
color: "#313131"
height: 1
}
// ------------- Transfer tab --------------- // ------------- Transfer tab ---------------
MoneroComponents.MenuButton { MoneroComponents.MenuButton {
id: transferButton id: transferButton

View file

@ -67,7 +67,7 @@ Rectangle {
property Mining miningView: Mining { } property Mining miningView: Mining { }
property AddressBook addressBookView: AddressBook { } property AddressBook addressBookView: AddressBook { }
property Keys keysView: Keys { } property Keys keysView: Keys { }
property Account accountView: Account { }
signal paymentClicked(string address, string paymentId, string amount, int mixinCount, int priority, string description) signal paymentClicked(string address, string paymentId, string amount, int mixinCount, int priority, string description)
signal sweepUnmixableClicked() signal sweepUnmixableClicked()
@ -160,7 +160,11 @@ Rectangle {
name: "Keys" name: "Keys"
PropertyChanges { target: root; currentView: keysView } PropertyChanges { target: root; currentView: keysView }
PropertyChanges { target: mainFlickable; contentHeight: keysView.keysHeight } PropertyChanges { target: mainFlickable; contentHeight: keysView.keysHeight }
} }, State {
name: "Account"
PropertyChanges { target: root; currentView: accountView }
PropertyChanges { target: mainFlickable; contentHeight: minHeight }
}
] ]
// color stripe at the top // color stripe at the top

View file

@ -44,6 +44,8 @@ Item {
property alias wrapMode: label.wrapMode property alias wrapMode: label.wrapMode
property alias horizontalAlignment: label.horizontalAlignment property alias horizontalAlignment: label.horizontalAlignment
property alias hoveredLink: label.hoveredLink property alias hoveredLink: label.hoveredLink
property alias elide: label.elide
property alias textWidth: label.width
signal linkActivated() signal linkActivated()
height: label.height * scaleRatio height: label.height * scaleRatio
width: label.width * scaleRatio width: label.width * scaleRatio

Binary file not shown.

After

Width:  |  Height:  |  Size: 399 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 760 B

View file

@ -55,6 +55,8 @@
#include "model/AddressBookModel.h" #include "model/AddressBookModel.h"
#include "Subaddress.h" #include "Subaddress.h"
#include "model/SubaddressModel.h" #include "model/SubaddressModel.h"
#include "SubaddressAccount.h"
#include "model/SubaddressAccountModel.h"
#include "wallet/api/wallet2_api.h" #include "wallet/api/wallet2_api.h"
#include "Logger.h" #include "Logger.h"
#include "MainApp.h" #include "MainApp.h"
@ -208,6 +210,12 @@ int main(int argc, char *argv[])
qmlRegisterUncreatableType<Subaddress>("moneroComponents.Subaddress", 1, 0, "Subaddress", qmlRegisterUncreatableType<Subaddress>("moneroComponents.Subaddress", 1, 0, "Subaddress",
"Subaddress can't be instantiated directly"); "Subaddress can't be instantiated directly");
qmlRegisterUncreatableType<SubaddressAccountModel>("moneroComponents.SubaddressAccountModel", 1, 0, "SubaddressAccountModel",
"SubaddressAccountModel can't be instantiated directly");
qmlRegisterUncreatableType<SubaddressAccount>("moneroComponents.SubaddressAccount", 1, 0, "SubaddressAccount",
"SubaddressAccount can't be instantiated directly");
qRegisterMetaType<PendingTransaction::Priority>(); qRegisterMetaType<PendingTransaction::Priority>();
qRegisterMetaType<TransactionInfo::Direction>(); qRegisterMetaType<TransactionInfo::Direction>();
qRegisterMetaType<TransactionHistoryModel::TransactionInfoRole>(); qRegisterMetaType<TransactionHistoryModel::TransactionInfoRole>();

View file

@ -86,10 +86,11 @@ ApplicationWindow {
// true if wallet ever synchronized // true if wallet ever synchronized
property bool walletInitialized : false property bool walletInitialized : false
// Current selected address / subaddress (Receive page) // Current selected address / subaddress / (Receive/Account page)
property var current_address property var current_address
property var current_address_label: "Primary" property var current_address_label: "Primary"
property int current_subaddress_table_index: 0 property int current_subaddress_table_index: 0
property int current_subaddress_account_table_index: 0
function altKeyReleased() { ctrlPressed = false; } function altKeyReleased() { ctrlPressed = false; }
@ -117,6 +118,7 @@ ApplicationWindow {
else if(seq === "Ctrl+E") middlePanel.state = "Settings" else if(seq === "Ctrl+E") middlePanel.state = "Settings"
else if(seq === "Ctrl+Y") leftPanel.keysClicked() else if(seq === "Ctrl+Y") leftPanel.keysClicked()
else if(seq === "Ctrl+D") middlePanel.state = "Advanced" else if(seq === "Ctrl+D") middlePanel.state = "Advanced"
else if(seq === "Ctrl+T") middlePanel.state = "Account"
else if(seq === "Ctrl+Tab" || seq === "Alt+Tab") { else if(seq === "Ctrl+Tab" || seq === "Alt+Tab") {
/* /*
if(middlePanel.state === "Transfer") middlePanel.state = "Receive" if(middlePanel.state === "Transfer") middlePanel.state = "Receive"
@ -128,7 +130,8 @@ ApplicationWindow {
else if(middlePanel.state === "Mining") middlePanel.state = "Sign" else if(middlePanel.state === "Mining") middlePanel.state = "Sign"
else if(middlePanel.state === "Sign") middlePanel.state = "Settings" else if(middlePanel.state === "Sign") middlePanel.state = "Settings"
*/ */
if(middlePanel.state === "Settings") middlePanel.state = "Transfer" if(middlePanel.state === "Settings") middlePanel.state = "Account"
else if(middlePanel.state === "Account") middlePanel.state = "Transfer"
else if(middlePanel.state === "Transfer") middlePanel.state = "AddressBook" else if(middlePanel.state === "Transfer") middlePanel.state = "AddressBook"
else if(middlePanel.state === "AddressBook") middlePanel.state = "Receive" else if(middlePanel.state === "AddressBook") middlePanel.state = "Receive"
else if(middlePanel.state === "Receive") middlePanel.state = "History" else if(middlePanel.state === "Receive") middlePanel.state = "History"
@ -156,7 +159,8 @@ ApplicationWindow {
else if(middlePanel.state === "History") middlePanel.state = "Receive" else if(middlePanel.state === "History") middlePanel.state = "Receive"
else if(middlePanel.state === "Receive") middlePanel.state = "AddressBook" else if(middlePanel.state === "Receive") middlePanel.state = "AddressBook"
else if(middlePanel.state === "AddressBook") middlePanel.state = "Transfer" else if(middlePanel.state === "AddressBook") middlePanel.state = "Transfer"
else if(middlePanel.state === "Transfer") middlePanel.state = "Settings" else if(middlePanel.state === "Transfer") middlePanel.state = "Account"
else if(middlePanel.state === "Account") middlePanel.state = "Settings"
} }
if (middlePanel.state !== "Advanced") updateBalance(); if (middlePanel.state !== "Advanced") updateBalance();
@ -368,6 +372,9 @@ ApplicationWindow {
leftPanel.unlockedBalanceText = balance_unlocked; leftPanel.unlockedBalanceText = balance_unlocked;
middlePanel.balanceText = balance; middlePanel.balanceText = balance;
leftPanel.balanceText = balance; leftPanel.balanceText = balance;
var accountLabel = currentWallet.getSubaddressLabel(currentWallet.currentSubaddressAccount, 0);
leftPanel.balanceLabelText = qsTr("Balance (#%1%2)").arg(currentWallet.currentSubaddressAccount).arg(accountLabel === "" ? "" : (" " + accountLabel));
} }
function onWalletConnectionStatusChanged(status){ function onWalletConnectionStatusChanged(status){
@ -1435,6 +1442,15 @@ ApplicationWindow {
} }
onKeysClicked: Utils.showSeedPage(); onKeysClicked: Utils.showSeedPage();
onAccountClicked: {
middlePanel.state = "Account";
middlePanel.flickable.contentY = 0;
if(isMobile) {
hideMenu();
}
updateBalance();
}
} }
RightPanel { RightPanel {

View file

@ -50,6 +50,8 @@ HEADERS += \
src/libwalletqt/AddressBook.h \ src/libwalletqt/AddressBook.h \
src/model/SubaddressModel.h \ src/model/SubaddressModel.h \
src/libwalletqt/Subaddress.h \ src/libwalletqt/Subaddress.h \
src/model/SubaddressAccountModel.h \
src/libwalletqt/SubaddressAccount.h \
src/zxcvbn-c/zxcvbn.h \ src/zxcvbn-c/zxcvbn.h \
src/libwalletqt/UnsignedTransaction.h \ src/libwalletqt/UnsignedTransaction.h \
Logger.h \ Logger.h \
@ -76,6 +78,8 @@ SOURCES += main.cpp \
src/libwalletqt/AddressBook.cpp \ src/libwalletqt/AddressBook.cpp \
src/model/SubaddressModel.cpp \ src/model/SubaddressModel.cpp \
src/libwalletqt/Subaddress.cpp \ src/libwalletqt/Subaddress.cpp \
src/model/SubaddressAccountModel.cpp \
src/libwalletqt/SubaddressAccount.cpp \
src/zxcvbn-c/zxcvbn.c \ src/zxcvbn-c/zxcvbn.c \
src/libwalletqt/UnsignedTransaction.cpp \ src/libwalletqt/UnsignedTransaction.cpp \
Logger.cpp \ Logger.cpp \

352
pages/Account.qml Normal file
View file

@ -0,0 +1,352 @@
// Copyright (c) 2014-2019, 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
import QtQuick.Controls 2.0
import QtQuick.Controls.Styles 1.4
import QtQuick.Layouts 1.1
import QtQuick.Dialogs 1.2
import "../components" as MoneroComponents
import moneroComponents.Clipboard 1.0
import moneroComponents.Wallet 1.0
import moneroComponents.WalletManager 1.0
import moneroComponents.TransactionHistory 1.0
import moneroComponents.TransactionHistoryModel 1.0
import "../js/TxUtils.js" as TxUtils
Rectangle {
id: pageAccount
color: "transparent"
property var model
property alias accountHeight: mainLayout.height
property bool selectAndSend: false
function renameSubaddressAccountLabel(_index){
inputDialog.labelText = qsTr("Set the label of the selected account:") + translationManager.emptyString;
inputDialog.inputText = appWindow.currentWallet.getSubaddressLabel(_index, 0);
inputDialog.onAcceptedCallback = function() {
appWindow.currentWallet.subaddressAccount.setLabel(_index, inputDialog.inputText)
}
inputDialog.onRejectedCallback = null;
inputDialog.open()
}
Clipboard { id: clipboard }
/* main layout */
ColumnLayout {
id: mainLayout
anchors.margins: (isMobile)? 17 * scaleRatio : 20 * scaleRatio
anchors.topMargin: 40 * scaleRatio
anchors.left: parent.left
anchors.top: parent.top
anchors.right: parent.right
spacing: 20 * scaleRatio
ColumnLayout {
id: balanceRow
visible: !selectAndSend
spacing: 0
MoneroComponents.LabelSubheader {
Layout.fillWidth: true
textFormat: Text.RichText
text: qsTr("Balance All")
}
RowLayout {
Layout.topMargin: 22 * scaleRatio
Text {
text: qsTr("Total balance: ")
Layout.fillWidth: true
color: "#757575"
font.pixelSize: 14
font.family: MoneroComponents.Style.fontRegular.name
}
Text {
id: balanceAll
font.family: MoneroComponents.Style.fontRegular.name
font.pixelSize: 14
color: MoneroComponents.Style.white
MouseArea {
hoverEnabled: true
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onEntered: {
parent.color = MoneroComponents.Style.orange
}
onExited: {
parent.color = MoneroComponents.Style.white
}
onClicked: {
console.log("Copied to clipboard");
clipboard.setText(parent.text);
appWindow.showStatusMessage(qsTr("Copied to clipboard"),3)
}
}
}
}
RowLayout {
Layout.topMargin: 10 * scaleRatio
Text {
text: qsTr("Total unlocked balance: ")
Layout.fillWidth: true
color: "#757575"
font.pixelSize: 14
font.family: MoneroComponents.Style.fontRegular.name
}
Text {
id: unlockedBalanceAll
font.family: MoneroComponents.Style.fontRegular.name
font.pixelSize: 14
color: MoneroComponents.Style.white
MouseArea {
hoverEnabled: true
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onEntered: {
parent.color = MoneroComponents.Style.orange
}
onExited: {
parent.color = MoneroComponents.Style.white
}
onClicked: {
console.log("Copied to clipboard");
clipboard.setText(parent.text);
appWindow.showStatusMessage(qsTr("Copied to clipboard"),3)
}
}
}
}
}
ColumnLayout {
id: addressRow
spacing: 0
MoneroComponents.LabelSubheader {
Layout.fillWidth: true
textFormat: Text.RichText
text: qsTr("Accounts")
}
ColumnLayout {
id: subaddressAccountListRow
property int subaddressAccountListItemHeight: 50 * scaleRatio
Layout.topMargin: 6 * scaleRatio
Layout.fillWidth: true
Layout.minimumWidth: 240
Layout.preferredHeight: subaddressAccountListItemHeight * subaddressAccountListView.count
visible: subaddressAccountListView.count >= 1
ListView {
id: subaddressAccountListView
Layout.fillWidth: true
anchors.fill: parent
clip: true
boundsBehavior: ListView.StopAtBounds
delegate: Rectangle {
id: tableItem2
height: subaddressAccountListRow.subaddressAccountListItemHeight
width: parent.width
Layout.fillWidth: true
color: "transparent"
Rectangle {
anchors.right: parent.right
anchors.left: parent.left
anchors.top: parent.top
height: 1
color: "#404040"
visible: index !== 0
}
Rectangle {
anchors.fill: parent
anchors.topMargin: 5 * scaleRatio
anchors.rightMargin: 80 * scaleRatio
color: "transparent"
MoneroComponents.Label {
id: idLabel
color: index === appWindow.current_subaddress_account_table_index ? "white" : "#757575"
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: 6 * scaleRatio
fontSize: 14 * scaleRatio
fontBold: true
text: "#" + index
}
MoneroComponents.Label {
id: nameLabel
color: "#a5a5a5"
anchors.verticalCenter: parent.verticalCenter
anchors.left: idLabel.right
anchors.leftMargin: 6 * scaleRatio
fontSize: 14 * scaleRatio
fontBold: true
text: label
elide: Text.ElideRight
textWidth: addressLabel.x - nameLabel.x - 1
}
MoneroComponents.Label {
id: addressLabel
color: "white"
anchors.verticalCenter: parent.verticalCenter
anchors.left: balanceLabel.left
anchors.leftMargin: (mainLayout.width < 510 ? -70 : -125) * scaleRatio
fontSize: 14 * scaleRatio
fontBold: true
text: TxUtils.addressTruncate(address, mainLayout.width < 510 ? 3 : 6)
}
MoneroComponents.Label {
id: balanceLabel
color: "white"
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.right
anchors.leftMargin: (mainLayout.width < 510 ? -120 : -180) * scaleRatio
fontSize: 14 * scaleRatio
fontBold: true
text: qsTr("Balance: ") + balance
elide: mainLayout.width < 510 ? Text.ElideRight : Text.ElideNone
textWidth: 120
}
MouseArea {
cursorShape: Qt.PointingHandCursor
anchors.fill: parent
hoverEnabled: true
onEntered: {
tableItem2.color = "#26FFFFFF"
}
onExited: {
tableItem2.color = "transparent"
}
onClicked: {
if (index == subaddressAccountListView.currentIndex && selectAndSend) {
appWindow.showPageRequest("Transfer");
}
subaddressAccountListView.currentIndex = index;
}
}
}
MoneroComponents.IconButton {
id: renameButton
imageSource: "../images/editIcon.png"
anchors.right: parent.right
anchors.rightMargin: 30 * scaleRatio
anchors.topMargin: 1 * scaleRatio
onClicked: {
renameSubaddressAccountLabel(index);
}
}
MoneroComponents.IconButton {
id: copyButton
imageSource: "../images/dropdownCopy.png"
anchors.right: parent.right
onClicked: {
console.log("Address copied to clipboard");
clipboard.setText(address);
appWindow.showStatusMessage(qsTr("Address copied to clipboard"),3);
}
}
}
onCurrentItemChanged: {
// reset global vars
appWindow.current_subaddress_account_table_index = subaddressAccountListView.currentIndex;
appWindow.currentWallet.switchSubaddressAccount(appWindow.current_subaddress_account_table_index);
appWindow.onWalletUpdate();
}
onCurrentIndexChanged: {
if (selectAndSend) {
appWindow.showPageRequest("Transfer");
}
}
}
}
Rectangle {
color: "#404040"
Layout.fillWidth: true
height: 1
}
MoneroComponents.CheckBox {
id: addNewAccountCheckbox
visible: !selectAndSend
border: false
checkedIcon: "qrc:///images/plus-in-circle-medium-white.png"
uncheckedIcon: "qrc:///images/plus-in-circle-medium-white.png"
fontSize: 14 * scaleRatio
iconOnTheLeft: true
Layout.fillWidth: true
Layout.topMargin: 10 * scaleRatio
text: qsTr("Create new account") + translationManager.emptyString;
onClicked: {
inputDialog.labelText = qsTr("Set the label of the new account:") + translationManager.emptyString
inputDialog.inputText = qsTr("(Untitled)")
inputDialog.onAcceptedCallback = function() {
appWindow.currentWallet.subaddressAccount.addRow(inputDialog.inputText)
appWindow.currentWallet.switchSubaddressAccount(appWindow.currentWallet.numSubaddressAccounts() - 1)
current_subaddress_account_table_index = appWindow.currentWallet.numSubaddressAccounts() - 1
appWindow.onWalletUpdate();
}
inputDialog.onRejectedCallback = null;
inputDialog.open()
}
}
}
}
function onPageCompleted() {
console.log("account");
if (appWindow.currentWallet !== undefined) {
appWindow.currentWallet.subaddressAccount.refresh();
subaddressAccountListView.model = appWindow.currentWallet.subaddressAccountModel;
appWindow.currentWallet.subaddress.refresh(appWindow.currentWallet.currentSubaddressAccount)
balanceAll.text = walletManager.displayAmount(appWindow.currentWallet.balanceAll())
unlockedBalanceAll.text = walletManager.displayAmount(appWindow.currentWallet.unlockedBalanceAll())
}
}
function onPageClosed() {
selectAndSend = false;
}
}

View file

@ -137,7 +137,13 @@ Rectangle {
id: amountLine id: amountLine
Layout.fillWidth: true Layout.fillWidth: true
inlineIcon: true inlineIcon: true
labelText: qsTr("Amount") + translationManager.emptyString labelText: qsTr("<style type='text/css'>a {text-decoration: none; color: #858585; font-size: 14px;}</style>\
Amount <font size='2'> ( </font> <a href='#'>Change account</a><font size='2'> )</font>")
+ translationManager.emptyString
onLabelLinkActivated: {
middlePanel.accountView.selectAndSend = true;
appWindow.showPageRequest("Account")
}
placeholderText: qsTr("") + translationManager.emptyString placeholderText: qsTr("") + translationManager.emptyString
width: 100 * scaleRatio width: 100 * scaleRatio
fontBold: true fontBold: true

View file

@ -17,6 +17,7 @@
<file>images/whatIsIcon@2x.png</file> <file>images/whatIsIcon@2x.png</file>
<file>images/lockIcon.png</file> <file>images/lockIcon.png</file>
<file>components/MenuButton.qml</file> <file>components/MenuButton.qml</file>
<file>pages/Account.qml</file>
<file>pages/Transfer.qml</file> <file>pages/Transfer.qml</file>
<file>pages/History.qml</file> <file>pages/History.qml</file>
<file>pages/AddressBook.qml</file> <file>pages/AddressBook.qml</file>
@ -232,6 +233,8 @@
<file>images/eyeHide@2x.png</file> <file>images/eyeHide@2x.png</file>
<file>images/eyeShow.png</file> <file>images/eyeShow.png</file>
<file>images/eyeShow@2x.png</file> <file>images/eyeShow@2x.png</file>
<file>images/plus-in-circle-medium-white.png</file>
<file>images/plus-in-circle-medium-white@2x.png</file>
<file>pages/merchant/Merchant.qml</file> <file>pages/merchant/Merchant.qml</file>
<file>pages/merchant/MerchantCheckbox.qml</file> <file>pages/merchant/MerchantCheckbox.qml</file>
<file>pages/merchant/MerchantTrackingList.qml</file> <file>pages/merchant/MerchantTrackingList.qml</file>

View file

@ -0,0 +1,56 @@
#include "SubaddressAccount.h"
#include <QDebug>
SubaddressAccount::SubaddressAccount(Monero::SubaddressAccount *subaddressAccountImpl, QObject *parent)
: QObject(parent), m_subaddressAccountImpl(subaddressAccountImpl)
{
qDebug(__FUNCTION__);
getAll();
}
QList<Monero::SubaddressAccountRow*> SubaddressAccount::getAll(bool update) const
{
qDebug(__FUNCTION__);
emit refreshStarted();
if(update)
m_rows.clear();
if (m_rows.empty()){
for (auto &row: m_subaddressAccountImpl->getAll()) {
m_rows.append(row);
}
}
emit refreshFinished();
return m_rows;
}
Monero::SubaddressAccountRow * SubaddressAccount::getRow(int index) const
{
return m_rows.at(index);
}
void SubaddressAccount::addRow(const QString &label) const
{
m_subaddressAccountImpl->addRow(label.toStdString());
getAll(true);
}
void SubaddressAccount::setLabel(quint32 accountIndex, const QString &label) const
{
m_subaddressAccountImpl->setLabel(accountIndex, label.toStdString());
getAll(true);
}
void SubaddressAccount::refresh() const
{
m_subaddressAccountImpl->refresh();
getAll(true);
}
quint64 SubaddressAccount::count() const
{
return m_rows.size();
}

View file

@ -0,0 +1,33 @@
#ifndef SUBADDRESSACCOUNT_H
#define SUBADDRESSACCOUNT_H
#include <wallet/api/wallet2_api.h>
#include <QObject>
#include <QList>
#include <QDateTime>
class SubaddressAccount : public QObject
{
Q_OBJECT
public:
Q_INVOKABLE QList<Monero::SubaddressAccountRow*> getAll(bool update = false) const;
Q_INVOKABLE Monero::SubaddressAccountRow * getRow(int index) const;
Q_INVOKABLE void addRow(const QString &label) const;
Q_INVOKABLE void setLabel(quint32 accountIndex, const QString &label) const;
Q_INVOKABLE void refresh() const;
quint64 count() const;
signals:
void refreshStarted() const;
void refreshFinished() const;
public slots:
private:
explicit SubaddressAccount(Monero::SubaddressAccount * subaddressAccountImpl, QObject *parent);
friend class Wallet;
Monero::SubaddressAccount * m_subaddressAccountImpl;
mutable QList<Monero::SubaddressAccountRow*> m_rows;
};
#endif // SUBADDRESSACCOUNT_H

View file

@ -4,10 +4,12 @@
#include "TransactionHistory.h" #include "TransactionHistory.h"
#include "AddressBook.h" #include "AddressBook.h"
#include "Subaddress.h" #include "Subaddress.h"
#include "SubaddressAccount.h"
#include "model/TransactionHistoryModel.h" #include "model/TransactionHistoryModel.h"
#include "model/TransactionHistorySortFilterModel.h" #include "model/TransactionHistorySortFilterModel.h"
#include "model/AddressBookModel.h" #include "model/AddressBookModel.h"
#include "model/SubaddressModel.h" #include "model/SubaddressModel.h"
#include "model/SubaddressAccountModel.h"
#include "wallet/api/wallet2_api.h" #include "wallet/api/wallet2_api.h"
#include <QFile> #include <QFile>
@ -357,6 +359,7 @@ bool Wallet::refresh()
bool result = m_walletImpl->refresh(); bool result = m_walletImpl->refresh();
m_history->refresh(currentSubaddressAccount()); m_history->refresh(currentSubaddressAccount());
m_subaddress->refresh(currentSubaddressAccount()); m_subaddress->refresh(currentSubaddressAccount());
m_subaddressAccount->getAll(true);
if (result) if (result)
emit updated(); emit updated();
return result; return result;
@ -543,6 +546,20 @@ SubaddressModel *Wallet::subaddressModel()
return m_subaddressModel; return m_subaddressModel;
} }
SubaddressAccount *Wallet::subaddressAccount() const
{
return m_subaddressAccount;
}
SubaddressAccountModel *Wallet::subaddressAccountModel() const
{
if (!m_subaddressAccountModel) {
Wallet * w = const_cast<Wallet*>(this);
m_subaddressAccountModel = new SubaddressAccountModel(w,m_subaddressAccount);
}
return m_subaddressAccountModel;
}
QString Wallet::generatePaymentId() const QString Wallet::generatePaymentId() const
{ {
return QString::fromStdString(Monero::Wallet::genPaymentId()); return QString::fromStdString(Monero::Wallet::genPaymentId());
@ -858,6 +875,8 @@ Wallet::Wallet(Monero::Wallet *w, QObject *parent)
, m_addressBookModel(nullptr) , m_addressBookModel(nullptr)
, m_subaddress(nullptr) , m_subaddress(nullptr)
, m_subaddressModel(nullptr) , m_subaddressModel(nullptr)
, m_subaddressAccount(nullptr)
, m_subaddressAccountModel(nullptr)
, m_daemonBlockChainHeight(0) , m_daemonBlockChainHeight(0)
, m_daemonBlockChainHeightTtl(DAEMON_BLOCKCHAIN_HEIGHT_CACHE_TTL_SECONDS) , m_daemonBlockChainHeightTtl(DAEMON_BLOCKCHAIN_HEIGHT_CACHE_TTL_SECONDS)
, m_daemonBlockChainTargetHeight(0) , m_daemonBlockChainTargetHeight(0)
@ -868,6 +887,7 @@ Wallet::Wallet(Monero::Wallet *w, QObject *parent)
m_history = new TransactionHistory(m_walletImpl->history(), this); m_history = new TransactionHistory(m_walletImpl->history(), this);
m_addressBook = new AddressBook(m_walletImpl->addressBook(), this); m_addressBook = new AddressBook(m_walletImpl->addressBook(), this);
m_subaddress = new Subaddress(m_walletImpl->subaddress(), this); m_subaddress = new Subaddress(m_walletImpl->subaddress(), this);
m_subaddressAccount = new SubaddressAccount(m_walletImpl->subaddressAccount(), this);
m_walletListener = new WalletListenerImpl(this); m_walletListener = new WalletListenerImpl(this);
m_walletImpl->setListener(m_walletListener); m_walletImpl->setListener(m_walletListener);
m_connectionStatus = Wallet::ConnectionStatus_Disconnected; m_connectionStatus = Wallet::ConnectionStatus_Disconnected;
@ -893,6 +913,8 @@ Wallet::~Wallet()
m_addressBook = NULL; m_addressBook = NULL;
delete m_subaddress; delete m_subaddress;
m_subaddress = NULL; m_subaddress = NULL;
delete m_subaddressAccount;
m_subaddressAccount = NULL;
//Monero::WalletManagerFactory::getWalletManager()->closeWallet(m_walletImpl); //Monero::WalletManagerFactory::getWalletManager()->closeWallet(m_walletImpl);
if(status() == Status_Critical) if(status() == Status_Critical)
qDebug("Not storing wallet cache"); qDebug("Not storing wallet cache");

View file

@ -24,6 +24,8 @@ class AddressBook;
class AddressBookModel; class AddressBookModel;
class Subaddress; class Subaddress;
class SubaddressModel; class SubaddressModel;
class SubaddressAccount;
class SubaddressAccountModel;
class Wallet : public QObject class Wallet : public QObject
{ {
@ -44,6 +46,8 @@ class Wallet : public QObject
Q_PROPERTY(AddressBook * addressBook READ addressBook) Q_PROPERTY(AddressBook * addressBook READ addressBook)
Q_PROPERTY(SubaddressModel * subaddressModel READ subaddressModel) Q_PROPERTY(SubaddressModel * subaddressModel READ subaddressModel)
Q_PROPERTY(Subaddress * subaddress READ subaddress) Q_PROPERTY(Subaddress * subaddress READ subaddress)
Q_PROPERTY(SubaddressAccountModel * subaddressAccountModel READ subaddressAccountModel)
Q_PROPERTY(SubaddressAccount * subaddressAccount READ subaddressAccount)
Q_PROPERTY(bool viewOnly READ viewOnly) Q_PROPERTY(bool viewOnly READ viewOnly)
Q_PROPERTY(QString secretViewKey READ getSecretViewKey) Q_PROPERTY(QString secretViewKey READ getSecretViewKey)
Q_PROPERTY(QString publicViewKey READ getPublicViewKey) Q_PROPERTY(QString publicViewKey READ getPublicViewKey)
@ -234,6 +238,12 @@ public:
//! returns subadress model //! returns subadress model
SubaddressModel *subaddressModel(); SubaddressModel *subaddressModel();
//! returns subaddress account
SubaddressAccount *subaddressAccount() const;
//! returns subadress account model
SubaddressAccountModel *subaddressAccountModel() const;
//! generate payment id //! generate payment id
Q_INVOKABLE QString generatePaymentId() const; Q_INVOKABLE QString generatePaymentId() const;
@ -348,6 +358,8 @@ private:
mutable AddressBookModel * m_addressBookModel; mutable AddressBookModel * m_addressBookModel;
Subaddress * m_subaddress; Subaddress * m_subaddress;
mutable SubaddressModel * m_subaddressModel; mutable SubaddressModel * m_subaddressModel;
SubaddressAccount * m_subaddressAccount;
mutable SubaddressAccountModel * m_subaddressAccountModel;
QMutex m_connectionStatusMutex; QMutex m_connectionStatusMutex;
bool m_connectionStatusRunning; bool m_connectionStatusRunning;
QString m_daemonUsername; QString m_daemonUsername;

View file

@ -0,0 +1,66 @@
#include "SubaddressAccountModel.h"
#include "SubaddressAccount.h"
#include <QDebug>
#include <QHash>
#include <wallet/api/wallet2_api.h>
SubaddressAccountModel::SubaddressAccountModel(QObject *parent, SubaddressAccount *subaddressAccount)
: QAbstractListModel(parent), m_subaddressAccount(subaddressAccount)
{
qDebug(__FUNCTION__);
connect(m_subaddressAccount,SIGNAL(refreshStarted()),this,SLOT(startReset()));
connect(m_subaddressAccount,SIGNAL(refreshFinished()),this,SLOT(endReset()));
}
void SubaddressAccountModel::startReset(){
qDebug("SubaddressAccountModel::startReset");
beginResetModel();
}
void SubaddressAccountModel::endReset(){
qDebug("SubaddressAccountModel::endReset");
endResetModel();
}
int SubaddressAccountModel::rowCount(const QModelIndex &parent) const
{
return m_subaddressAccount->count();
}
QVariant SubaddressAccountModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid() || index.row() < 0 || (unsigned)index.row() >= m_subaddressAccount->count())
return {};
Monero::SubaddressAccountRow * sr = m_subaddressAccount->getRow(index.row());
QVariant result = "";
switch (role) {
case SubaddressAccountAddressRole:
result = QString::fromStdString(sr->getAddress());
break;
case SubaddressAccountLabelRole:
result = QString::fromStdString(sr->getLabel());
break;
case SubaddressAccountBalanceRole:
result = QString::fromStdString(sr->getBalance());
break;
case SubaddressAccountUnlockedBalanceRole:
result = QString::fromStdString(sr->getUnlockedBalance());
break;
}
return result;
}
QHash<int, QByteArray> SubaddressAccountModel::roleNames() const
{
static QHash<int, QByteArray> roleNames;
if (roleNames.empty())
{
roleNames.insert(SubaddressAccountAddressRole, "address");
roleNames.insert(SubaddressAccountLabelRole, "label");
roleNames.insert(SubaddressAccountBalanceRole, "balance");
roleNames.insert(SubaddressAccountUnlockedBalanceRole, "unlockedBalance");
}
return roleNames;
}

View file

@ -0,0 +1,36 @@
#ifndef SUBADDRESSACCOUNTMODEL_H
#define SUBADDRESSACCOUNTMODEL_H
#include <QAbstractListModel>
class SubaddressAccount;
class SubaddressAccountModel : public QAbstractListModel
{
Q_OBJECT
public:
enum SubaddressAccountRowRole {
SubaddressAccountRole = Qt::UserRole + 1, // for the SubaddressAccountRow object;
SubaddressAccountAddressRole,
SubaddressAccountLabelRole,
SubaddressAccountBalanceRole,
SubaddressAccountUnlockedBalanceRole,
};
Q_ENUM(SubaddressAccountRowRole)
SubaddressAccountModel(QObject *parent, SubaddressAccount *subaddressAccount);
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
QHash<int, QByteArray> roleNames() const override;
public slots:
void startReset();
void endReset();
private:
SubaddressAccount *m_subaddressAccount;
};
#endif // SUBADDRESSACCOUNTMODEL_H