Subaddresses minimal version: supports default account only

This commit is contained in:
kenshi84
2017-07-04 12:34:09 +09:00
parent 3b069ec049
commit cee0474e37
28 changed files with 934 additions and 56 deletions

View File

@@ -50,6 +50,16 @@ quint64 PendingTransaction::txCount() const
return m_pimpl->txCount();
}
QList<QVariant> PendingTransaction::subaddrIndices() const
{
std::vector<std::set<uint32_t>> subaddrIndices = m_pimpl->subaddrIndices();
QList<QVariant> result;
for (const auto& x : subaddrIndices)
for (uint32_t i : x)
result.push_back(i);
return result;
}
void PendingTransaction::setFilename(const QString &fileName)
{
m_fileName = fileName;

View File

@@ -2,6 +2,8 @@
#define PENDINGTRANSACTION_H
#include <QObject>
#include <QList>
#include <QVariant>
#include <wallet/api/wallet2_api.h>
@@ -19,6 +21,7 @@ class PendingTransaction : public QObject
Q_PROPERTY(quint64 fee READ fee)
Q_PROPERTY(QStringList txid READ txid)
Q_PROPERTY(quint64 txCount READ txCount)
Q_PROPERTY(QList<QVariant> subaddrIndices READ subaddrIndices)
public:
enum Status {
@@ -44,6 +47,7 @@ public:
quint64 fee() const;
QStringList txid() const;
quint64 txCount() const;
QList<QVariant> subaddrIndices() const;
Q_INVOKABLE void setFilename(const QString &fileName);
private:

View File

@@ -0,0 +1,84 @@
// Copyright (c) 2018, 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.
#include "Subaddress.h"
#include <QDebug>
Subaddress::Subaddress(Monero::Subaddress *subaddressImpl, QObject *parent)
: QObject(parent), m_subaddressImpl(subaddressImpl)
{
qDebug(__FUNCTION__);
getAll();
}
QList<Monero::SubaddressRow*> Subaddress::getAll(bool update) const
{
qDebug(__FUNCTION__);
emit refreshStarted();
if(update)
m_rows.clear();
if (m_rows.empty()){
for (auto &row: m_subaddressImpl->getAll()) {
m_rows.append(row);
}
}
emit refreshFinished();
return m_rows;
}
Monero::SubaddressRow * Subaddress::getRow(int index) const
{
return m_rows.at(index);
}
void Subaddress::addRow(quint32 accountIndex, const QString &label) const
{
m_subaddressImpl->addRow(accountIndex, label.toStdString());
getAll(true);
}
void Subaddress::setLabel(quint32 accountIndex, quint32 addressIndex, const QString &label) const
{
m_subaddressImpl->setLabel(accountIndex, addressIndex, label.toStdString());
getAll(true);
}
void Subaddress::refresh(quint32 accountIndex) const
{
m_subaddressImpl->refresh(accountIndex);
getAll(true);
}
quint64 Subaddress::count() const
{
return m_rows.size();
}

View File

@@ -0,0 +1,61 @@
// Copyright (c) 2018, 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.
#ifndef SUBADDRESS_H
#define SUBADDRESS_H
#include <wallet/api/wallet2_api.h>
#include <QObject>
#include <QList>
#include <QDateTime>
class Subaddress : public QObject
{
Q_OBJECT
public:
Q_INVOKABLE QList<Monero::SubaddressRow*> getAll(bool update = false) const;
Q_INVOKABLE Monero::SubaddressRow * getRow(int index) const;
Q_INVOKABLE void addRow(quint32 accountIndex, const QString &label) const;
Q_INVOKABLE void setLabel(quint32 accountIndex, quint32 addressIndex, const QString &label) const;
Q_INVOKABLE void refresh(quint32 accountIndex) const;
quint64 count() const;
signals:
void refreshStarted() const;
void refreshFinished() const;
public slots:
private:
explicit Subaddress(Monero::Subaddress * subaddressImpl, QObject *parent);
friend class Wallet;
Monero::Subaddress * m_subaddressImpl;
mutable QList<Monero::SubaddressRow*> m_rows;
};
#endif // SUBADDRESS_H

View File

@@ -22,7 +22,7 @@ TransactionInfo *TransactionHistory::transaction(int index)
// return nullptr;
//}
QList<TransactionInfo *> TransactionHistory::getAll() const
QList<TransactionInfo *> TransactionHistory::getAll(quint32 accountIndex) const
{
// XXX this invalidates previously saved history that might be used by model
emit refreshStarted();
@@ -37,6 +37,10 @@ QList<TransactionInfo *> TransactionHistory::getAll() const
TransactionHistory * parent = const_cast<TransactionHistory*>(this);
for (const auto i : m_pimpl->getAll()) {
TransactionInfo * ti = new TransactionInfo(i, parent);
if (ti->subaddrAccount() != accountIndex) {
delete ti;
continue;
}
m_tinfo.append(ti);
// looking for transactions timestamp scope
if (ti->timestamp() >= lastDateTime) {
@@ -69,12 +73,12 @@ QList<TransactionInfo *> TransactionHistory::getAll() const
return m_tinfo;
}
void TransactionHistory::refresh()
void TransactionHistory::refresh(quint32 accountIndex)
{
// rebuilding transaction list in wallet_api;
m_pimpl->refresh();
// copying list here and keep track on every item to avoid memleaks
getAll();
getAll(accountIndex);
}
quint64 TransactionHistory::count() const

View File

@@ -23,8 +23,8 @@ class TransactionHistory : public QObject
public:
Q_INVOKABLE TransactionInfo *transaction(int index);
// Q_INVOKABLE TransactionInfo * transaction(const QString &id);
Q_INVOKABLE QList<TransactionInfo*> getAll() const;
Q_INVOKABLE void refresh();
Q_INVOKABLE QList<TransactionInfo*> getAll(quint32 accountIndex) const;
Q_INVOKABLE void refresh(quint32 accountIndex);
quint64 count() const;
QDateTime firstDateTime() const;
QDateTime lastDateTime() const;

View File

@@ -48,6 +48,24 @@ quint64 TransactionInfo::blockHeight() const
return m_pimpl->blockHeight();
}
QSet<quint32> TransactionInfo::subaddrIndex() const
{
QSet<quint32> result;
for (uint32_t i : m_pimpl->subaddrIndex())
result.insert(i);
return result;
}
quint32 TransactionInfo::subaddrAccount() const
{
return m_pimpl->subaddrAccount();
}
QString TransactionInfo::label() const
{
return QString::fromStdString(m_pimpl->label());
}
quint64 TransactionInfo::confirmations() const
{
return m_pimpl->confirmations();

View File

@@ -4,6 +4,7 @@
#include <wallet/api/wallet2_api.h>
#include <QObject>
#include <QDateTime>
#include <QSet>
class Transfer;
@@ -18,6 +19,9 @@ class TransactionInfo : public QObject
Q_PROPERTY(QString displayAmount READ displayAmount)
Q_PROPERTY(QString fee READ fee)
Q_PROPERTY(quint64 blockHeight READ blockHeight)
Q_PROPERTY(QSet<quint32> subaddrIndex READ subaddrIndex)
Q_PROPERTY(quint32 subaddrAccount READ subaddrAccount)
Q_PROPERTY(QString label READ label)
Q_PROPERTY(quint64 confirmations READ confirmations)
Q_PROPERTY(quint64 unlockTime READ unlockTime)
Q_PROPERTY(QString hash READ hash)
@@ -44,6 +48,9 @@ public:
QString displayAmount() const;
QString fee() const;
quint64 blockHeight() const;
QSet<quint32> subaddrIndex() const;
quint32 subaddrAccount() const;
QString label() const;
quint64 confirmations() const;
quint64 unlockTime() const;
//! transaction_id

View File

@@ -3,9 +3,11 @@
#include "UnsignedTransaction.h"
#include "TransactionHistory.h"
#include "AddressBook.h"
#include "Subaddress.h"
#include "model/TransactionHistoryModel.h"
#include "model/TransactionHistorySortFilterModel.h"
#include "model/AddressBookModel.h"
#include "model/SubaddressModel.h"
#include "wallet/api/wallet2_api.h"
#include <QFile>
@@ -155,9 +157,9 @@ bool Wallet::setPassword(const QString &password)
return m_walletImpl->setPassword(password.toStdString());
}
QString Wallet::address() const
QString Wallet::address(quint32 accountIndex, quint32 addressIndex) const
{
return QString::fromStdString(m_walletImpl->address());
return QString::fromStdString(m_walletImpl->address(accountIndex, addressIndex));
}
QString Wallet::path() const
@@ -241,14 +243,63 @@ bool Wallet::viewOnly() const
return m_walletImpl->watchOnly();
}
quint64 Wallet::balance() const
quint64 Wallet::balance(quint32 accountIndex) const
{
return m_walletImpl->balance();
return m_walletImpl->balance(accountIndex);
}
quint64 Wallet::unlockedBalance() const
quint64 Wallet::balanceAll() const
{
return m_walletImpl->unlockedBalance();
return m_walletImpl->balanceAll();
}
quint64 Wallet::unlockedBalance(quint32 accountIndex) const
{
return m_walletImpl->unlockedBalance(accountIndex);
}
quint64 Wallet::unlockedBalanceAll() const
{
return m_walletImpl->unlockedBalanceAll();
}
quint32 Wallet::currentSubaddressAccount() const
{
return m_currentSubaddressAccount;
}
void Wallet::switchSubaddressAccount(quint32 accountIndex)
{
if (accountIndex < numSubaddressAccounts())
{
m_currentSubaddressAccount = accountIndex;
m_subaddress->refresh(m_currentSubaddressAccount);
m_history->refresh(m_currentSubaddressAccount);
}
}
void Wallet::addSubaddressAccount(const QString& label)
{
m_walletImpl->addSubaddressAccount(label.toStdString());
switchSubaddressAccount(numSubaddressAccounts() - 1);
}
quint32 Wallet::numSubaddressAccounts() const
{
return m_walletImpl->numSubaddressAccounts();
}
quint32 Wallet::numSubaddresses(quint32 accountIndex) const
{
return m_walletImpl->numSubaddresses(accountIndex);
}
void Wallet::addSubaddress(const QString& label)
{
m_walletImpl->addSubaddress(currentSubaddressAccount(), label.toStdString());
}
QString Wallet::getSubaddressLabel(quint32 accountIndex, quint32 addressIndex) const
{
return QString::fromStdString(m_walletImpl->getSubaddressLabel(accountIndex, addressIndex));
}
void Wallet::setSubaddressLabel(quint32 accountIndex, quint32 addressIndex, const QString &label)
{
m_walletImpl->setSubaddressLabel(accountIndex, addressIndex, label.toStdString());
}
quint64 Wallet::blockChainHeight() const
@@ -288,7 +339,8 @@ quint64 Wallet::daemonBlockChainTargetHeight() const
bool Wallet::refresh()
{
bool result = m_walletImpl->refresh();
m_history->refresh();
m_history->refresh(currentSubaddressAccount());
m_subaddress->refresh(currentSubaddressAccount());
if (result)
emit updated();
return result;
@@ -324,9 +376,10 @@ PendingTransaction *Wallet::createTransaction(const QString &dst_addr, const QSt
quint64 amount, quint32 mixin_count,
PendingTransaction::Priority priority)
{
std::set<uint32_t> subaddr_indices;
Monero::PendingTransaction * ptImpl = m_walletImpl->createTransaction(
dst_addr.toStdString(), payment_id.toStdString(), amount, mixin_count,
static_cast<Monero::PendingTransaction::Priority>(priority));
static_cast<Monero::PendingTransaction::Priority>(priority), currentSubaddressAccount(), subaddr_indices);
PendingTransaction * result = new PendingTransaction(ptImpl,0);
return result;
}
@@ -351,9 +404,10 @@ void Wallet::createTransactionAsync(const QString &dst_addr, const QString &paym
PendingTransaction *Wallet::createTransactionAll(const QString &dst_addr, const QString &payment_id,
quint32 mixin_count, PendingTransaction::Priority priority)
{
std::set<uint32_t> subaddr_indices;
Monero::PendingTransaction * ptImpl = m_walletImpl->createTransaction(
dst_addr.toStdString(), payment_id.toStdString(), Monero::optional<uint64_t>(), mixin_count,
static_cast<Monero::PendingTransaction::Priority>(priority));
static_cast<Monero::PendingTransaction::Priority>(priority), currentSubaddressAccount(), subaddr_indices);
PendingTransaction * result = new PendingTransaction(ptImpl, this);
return result;
}
@@ -458,6 +512,18 @@ AddressBookModel *Wallet::addressBookModel() const
return m_addressBookModel;
}
Subaddress *Wallet::subaddress()
{
return m_subaddress;
}
SubaddressModel *Wallet::subaddressModel()
{
if (!m_subaddressModel) {
m_subaddressModel = new SubaddressModel(this, m_subaddress);
}
return m_subaddressModel;
}
QString Wallet::generatePaymentId() const
{
@@ -668,14 +734,18 @@ Wallet::Wallet(Monero::Wallet *w, QObject *parent)
, m_historyModel(nullptr)
, m_addressBook(nullptr)
, m_addressBookModel(nullptr)
, m_subaddress(nullptr)
, m_subaddressModel(nullptr)
, m_daemonBlockChainHeight(0)
, m_daemonBlockChainHeightTtl(DAEMON_BLOCKCHAIN_HEIGHT_CACHE_TTL_SECONDS)
, m_daemonBlockChainTargetHeight(0)
, m_daemonBlockChainTargetHeightTtl(DAEMON_BLOCKCHAIN_TARGET_HEIGHT_CACHE_TTL_SECONDS)
, m_connectionStatusTtl(WALLET_CONNECTION_STATUS_CACHE_TTL_SECONDS)
, m_currentSubaddressAccount(0)
{
m_history = new TransactionHistory(m_walletImpl->history(), this);
m_addressBook = new AddressBook(m_walletImpl->addressBook(), this);
m_subaddress = new Subaddress(m_walletImpl->subaddress(), this);
m_walletImpl->setListener(new WalletListenerImpl(this));
m_connectionStatus = Wallet::ConnectionStatus_Disconnected;
// start cache timers
@@ -696,6 +766,10 @@ Wallet::~Wallet()
delete m_history;
m_history = NULL;
delete m_addressBook;
m_addressBook = NULL;
delete m_subaddress;
m_subaddress = NULL;
//Monero::WalletManagerFactory::getWalletManager()->closeWallet(m_walletImpl);
if(status() == Status_Critical)
qDebug("Not storing wallet cache");

View File

@@ -20,6 +20,8 @@ class TransactionHistoryModel;
class TransactionHistorySortFilterModel;
class AddressBook;
class AddressBookModel;
class Subaddress;
class SubaddressModel;
class Wallet : public QObject
{
@@ -29,17 +31,17 @@ class Wallet : public QObject
Q_PROPERTY(Status status READ status)
Q_PROPERTY(bool testnet READ testnet)
// Q_PROPERTY(ConnectionStatus connected READ connected)
Q_PROPERTY(quint32 currentSubaddressAccount READ currentSubaddressAccount)
Q_PROPERTY(bool synchronized READ synchronized)
Q_PROPERTY(QString errorString READ errorString)
Q_PROPERTY(QString address READ address)
Q_PROPERTY(quint64 balance READ balance)
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 NOTIFY historyModelChanged)
Q_PROPERTY(QString path READ path)
Q_PROPERTY(AddressBookModel * addressBookModel READ addressBookModel)
Q_PROPERTY(AddressBook * addressBook READ addressBook)
Q_PROPERTY(SubaddressModel * subaddressModel READ subaddressModel)
Q_PROPERTY(Subaddress * subaddress READ subaddress)
Q_PROPERTY(bool viewOnly READ viewOnly)
Q_PROPERTY(QString secretViewKey READ getSecretViewKey)
Q_PROPERTY(QString publicViewKey READ getPublicViewKey)
@@ -98,7 +100,7 @@ public:
Q_INVOKABLE bool setPassword(const QString &password);
//! returns wallet's public address
QString address() const;
Q_INVOKABLE QString address(quint32 accountIndex, quint32 addressIndex) const;
//! returns wallet file's path
QString path() const;
@@ -126,10 +128,22 @@ public:
Q_INVOKABLE void setTrustedDaemon(bool arg);
//! returns balance
Q_INVOKABLE quint64 balance() const;
Q_INVOKABLE quint64 balance(quint32 accountIndex) const;
Q_INVOKABLE quint64 balanceAll() const;
//! returns unlocked balance
Q_INVOKABLE quint64 unlockedBalance() const;
Q_INVOKABLE quint64 unlockedBalance(quint32 accountIndex) const;
Q_INVOKABLE quint64 unlockedBalanceAll() const;
//! account/address management
quint32 currentSubaddressAccount() const;
Q_INVOKABLE void switchSubaddressAccount(quint32 accountIndex);
Q_INVOKABLE void addSubaddressAccount(const QString& label);
Q_INVOKABLE quint32 numSubaddressAccounts() const;
Q_INVOKABLE quint32 numSubaddresses(quint32 accountIndex) const;
Q_INVOKABLE void addSubaddress(const QString& label);
Q_INVOKABLE QString getSubaddressLabel(quint32 accountIndex, quint32 addressIndex) const;
Q_INVOKABLE void setSubaddressLabel(quint32 accountIndex, quint32 addressIndex, const QString &label);
//! returns if view only wallet
Q_INVOKABLE bool viewOnly() const;
@@ -209,6 +223,12 @@ public:
//! returns adress book model
AddressBookModel *addressBookModel() const;
//! returns subaddress
Subaddress *subaddress();
//! returns subadress model
SubaddressModel *subaddressModel();
//! generate payment id
Q_INVOKABLE QString generatePaymentId() const;
@@ -302,8 +322,11 @@ private:
int m_connectionStatusTtl;
mutable QTime m_connectionStatusTime;
mutable bool m_initialized;
uint32_t m_currentSubaddressAccount;
AddressBook * m_addressBook;
mutable AddressBookModel * m_addressBookModel;
Subaddress * m_subaddress;
mutable SubaddressModel * m_subaddressModel;
QMutex m_connectionStatusMutex;
bool m_connectionStatusRunning;
QString m_daemonUsername;

View File

@@ -49,7 +49,7 @@ Wallet *WalletManager::openWallet(const QString &path, const QString &password,
__PRETTY_FUNCTION__, qPrintable(path), testnet);
Monero::Wallet * w = m_pimpl->openWallet(path.toStdString(), password.toStdString(), testnet);
qDebug("%s: opened wallet: %s, status: %d", __PRETTY_FUNCTION__, w->address().c_str(), w->status());
qDebug("%s: opened wallet: %s, status: %d", __PRETTY_FUNCTION__, w->address(0, 0).c_str(), w->status());
m_currentWallet = new Wallet(w);
// move wallet to the GUI thread. Otherwise it wont be emitting signals
@@ -110,7 +110,7 @@ QString WalletManager::closeWallet()
QMutexLocker locker(&m_mutex);
QString result;
if (m_currentWallet) {
result = m_currentWallet->address();
result = m_currentWallet->address(0, 0);
delete m_currentWallet;
} else {
qCritical() << "Trying to close non existing wallet " << m_currentWallet;

View File

@@ -0,0 +1,89 @@
// Copyright (c) 2018, 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.
#include "SubaddressModel.h"
#include "Subaddress.h"
#include <QDebug>
#include <QHash>
#include <wallet/api/wallet2_api.h>
SubaddressModel::SubaddressModel(QObject *parent, Subaddress *subaddress)
: QAbstractListModel(parent), m_subaddress(subaddress)
{
qDebug(__FUNCTION__);
connect(m_subaddress,SIGNAL(refreshStarted()),this,SLOT(startReset()));
connect(m_subaddress,SIGNAL(refreshFinished()),this,SLOT(endReset()));
}
void SubaddressModel::startReset(){
qDebug(__FUNCTION__);
beginResetModel();
}
void SubaddressModel::endReset(){
qDebug(__FUNCTION__);
endResetModel();
}
int SubaddressModel::rowCount(const QModelIndex &parent) const
{
return m_subaddress->count();
}
QVariant SubaddressModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid() || index.row() < 0 || (unsigned)index.row() >= m_subaddress->count())
return {};
Monero::SubaddressRow * sr = m_subaddress->getRow(index.row());
if (!sr)
return {};
QVariant result = "";
switch (role) {
case SubaddressAddressRole:
result = QString::fromStdString(sr->getAddress());
break;
case SubaddressLabelRole:
result = index.row() == 0 ? tr("Primary address") : QString::fromStdString(sr->getLabel());
break;
}
return result;
}
QHash<int, QByteArray> SubaddressModel::roleNames() const
{
static QHash<int, QByteArray> roleNames;
if (roleNames.empty())
{
roleNames.insert(SubaddressAddressRole, "address");
roleNames.insert(SubaddressLabelRole, "label");
}
return roleNames;
}

View File

@@ -0,0 +1,62 @@
// Copyright (c) 2018, 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.
#ifndef SUBADDRESSMODEL_H
#define SUBADDRESSMODEL_H
#include <QAbstractListModel>
class Subaddress;
class SubaddressModel : public QAbstractListModel
{
Q_OBJECT
public:
enum SubaddressRowRole {
SubaddressRole = Qt::UserRole + 1, // for the SubaddressRow object;
SubaddressAddressRole,
SubaddressLabelRole,
};
Q_ENUM(SubaddressRowRole)
SubaddressModel(QObject *parent, Subaddress *subaddress);
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:
Subaddress *m_subaddress;
};
#endif // SUBADDRESSMODEL_H

View File

@@ -83,6 +83,25 @@ QVariant TransactionHistoryModel::data(const QModelIndex &index, int role) const
}
break;
case TransactionSubaddrIndexRole:
{
QString str = QString{""};
bool first = true;
for (quint32 i : tInfo->subaddrIndex()) {
if (!first)
str += QString{","};
first = false;
str += QString::number(i);
}
result = str;
}
break;
case TransactionSubaddrAccountRole:
result = tInfo->subaddrAccount();
break;
case TransactionLabelRole:
result = tInfo->subaddrIndex().size() == 1 && *tInfo->subaddrIndex().begin() == 0 ? tr("Primary address") : tInfo->label();
break;
case TransactionConfirmationsRole:
result = tInfo->confirmations();
break;
@@ -133,6 +152,9 @@ QHash<int, QByteArray> TransactionHistoryModel::roleNames() const
roleNames.insert(TransactionAtomicAmountRole, "atomicAmount");
roleNames.insert(TransactionFeeRole, "fee");
roleNames.insert(TransactionBlockHeightRole, "blockHeight");
roleNames.insert(TransactionSubaddrIndexRole, "subaddrIndex");
roleNames.insert(TransactionSubaddrAccountRole, "subaddrAccount");
roleNames.insert(TransactionLabelRole, "label");
roleNames.insert(TransactionConfirmationsRole, "confirmations");
roleNames.insert(TransactionConfirmationsRequiredRole, "confirmationsRequired");
roleNames.insert(TransactionHashRole, "hash");

View File

@@ -25,6 +25,9 @@ public:
TransactionDisplayAmountRole,
TransactionFeeRole,
TransactionBlockHeightRole,
TransactionSubaddrIndexRole,
TransactionSubaddrAccountRole,
TransactionLabelRole,
TransactionConfirmationsRole,
TransactionConfirmationsRequiredRole,
TransactionHashRole,