<commit_before>// Copyright (c) 2011-2014 The Bitcoin developers
// Copyright (c) 2014-2015 The Dash developers
// Copyright (c) 2015-2020 The PIVX developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "addresstablemodel.h"
#include "addressbook.h"

#include "guiutil.h"
#include "walletmodel.h"

#include "base58.h"
#include "wallet/wallet.h"
#include "askpassphrasedialog.h"

#include "sapling/key_io_sapling.h"

#include <algorithm>

#include <QDebug>
#include <QFont>

const QString AddressTableModel::Send = "S";
const QString AddressTableModel::Receive = "R";
const QString AddressTableModel::Zerocoin = "X";
const QString AddressTableModel::Delegator = "D";
const QString AddressTableModel::Delegable = "E";
const QString AddressTableModel::ColdStaking = "C";
const QString AddressTableModel::ColdStakingSend = "T";
const QString AddressTableModel::ShieldedReceive = "U";
const QString AddressTableModel::ShieldedSend = "V";

struct AddressTableEntry {
    enum Type {
        Sending,
        Receiving,
        Zerocoin,
        Delegator,
        Delegable,
        ColdStaking,
        ColdStakingSend,
        ShieldedReceive,
        ShieldedSend,
        Hidden /* QSortFilterProxyModel will filter these out */
    };

    Type type;
    QString label;
    QString address;
    QString pubcoin;
    uint creationTime;

    AddressTableEntry() {}
    AddressTableEntry(Type type, const QString &pubcoin):    type(type), pubcoin(pubcoin) {}
    AddressTableEntry(Type type, const QString& label, const QString& address, const uint _creationTime) : type(type), label(label), address(address), creationTime(_creationTime) {}
};

struct AddressTableEntryLessThan {
    bool operator()(const AddressTableEntry& a, const AddressTableEntry& b) const
    {
        return a.address < b.address;
    }
    bool operator()(const AddressTableEntry& a, const QString& b) const
    {
        return a.address < b;
    }
    bool operator()(const QString& a, const AddressTableEntry& b) const
    {
        return a < b.address;
    }
};

/* Determine address type from address purpose */
static AddressTableEntry::Type translateTransactionType(const QString& strPurpose, bool isMine)
{
    AddressTableEntry::Type addressType = AddressTableEntry::Hidden;
    // "refund" addresses aren't shown, and change addresses aren't in mapAddressBook at all.
    if (strPurpose ==  QString::fromStdString(AddressBook::AddressBookPurpose::SEND))
        addressType = AddressTableEntry::Sending;
    else if (strPurpose ==  QString::fromStdString(AddressBook::AddressBookPurpose::RECEIVE))
        addressType = AddressTableEntry::Receiving;
    else if (strPurpose == QString::fromStdString(AddressBook::AddressBookPurpose::DELEGATOR))
        addressType = AddressTableEntry::Delegator;
    else if (strPurpose == QString::fromStdString(AddressBook::AddressBookPurpose::DELEGABLE))
        addressType = AddressTableEntry::Delegable;
    else if (strPurpose == QString::fromStdString(AddressBook::AddressBookPurpose::COLD_STAKING))
        addressType = AddressTableEntry::ColdStaking;
    else if (strPurpose == QString::fromStdString(AddressBook::AddressBookPurpose::COLD_STAKING_SEND))
        addressType = AddressTableEntry::ColdStakingSend;
    else if (strPurpose == QString::fromStdString(AddressBook::AddressBookPurpose::SHIELDED_RECEIVE))
        addressType = AddressTableEntry::ShieldedReceive;
    else if (strPurpose == QString::fromStdString(AddressBook::AddressBookPurpose::SHIELDED_SEND))
        addressType = AddressTableEntry::ShieldedSend;
    else if (strPurpose == "unknown" || strPurpose == "") // if purpose not set, guess
        addressType = (isMine ? AddressTableEntry::Receiving : AddressTableEntry::Sending);
    return addressType;
}

static QString translateTypeToString(AddressTableEntry::Type type)
{
    switch (type) {
        case AddressTableEntry::Sending:
            return QObject::tr("Contact");
        case AddressTableEntry::Receiving:
            return QObject::tr("Receiving");
        case AddressTableEntry::Delegator:
            return QObject::tr("Delegator");
        case AddressTableEntry::Delegable:
            return QObject::tr("Delegable");
        case AddressTableEntry::ColdStaking:
            return QObject::tr("Cold Staking");
        case AddressTableEntry::ColdStakingSend:
            return QObject::tr("Cold Staking Contact");
        case AddressTableEntry::Hidden:
            return QObject::tr("Hidden");
        default:
            return QObject::tr("Unknown");
    }
}

// Private implementation
class AddressTablePriv
{
public:
    CWallet* wallet;
    QList<AddressTableEntry> cachedAddressTable;
    int sendNum = 0;
    int recvNum = 0;
    int dellNum = 0;
    int coldSendNum = 0;
    int shieldedSendNum = 0;
    AddressTableModel* parent;

    AddressTablePriv(CWallet* wallet, AddressTableModel* parent) : wallet(wallet), parent(parent) {}

    void refreshAddressTable()
    {
        cachedAddressTable.clear();
        {
            LOCK(wallet->cs_wallet);
            for (auto it = wallet->NewAddressBookIterator(); it.IsValid(); it.Next()) {
                auto addrBookData = it.GetValue();<commit_msg>GUI: Fixing export addressbook, shielded addresses missing type.<commit_after>// Copyright (c) 2011-2014 The Bitcoin developers
// Copyright (c) 2014-2015 The Dash developers
// Copyright (c) 2015-2020 The PIVX developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "addresstablemodel.h"
#include "addressbook.h"

#include "guiutil.h"
#include "walletmodel.h"

#include "base58.h"
#include "wallet/wallet.h"
#include "askpassphrasedialog.h"

#include "sapling/key_io_sapling.h"

#include <algorithm>

#include <QDebug>
#include <QFont>

const QString AddressTableModel::Send = "S";
const QString AddressTableModel::Receive = "R";
const QString AddressTableModel::Zerocoin = "X";
const QString AddressTableModel::Delegator = "D";
const QString AddressTableModel::Delegable = "E";
const QString AddressTableModel::ColdStaking = "C";
const QString AddressTableModel::ColdStakingSend = "T";
const QString AddressTableModel::ShieldedReceive = "U";
const QString AddressTableModel::ShieldedSend = "V";

struct AddressTableEntry {
    enum Type {
        Sending,
        Receiving,
        Zerocoin,
        Delegator,
        Delegable,
        ColdStaking,
        ColdStakingSend,
        ShieldedReceive,
        ShieldedSend,
        Hidden /* QSortFilterProxyModel will filter these out */
    };

    Type type;
    QString label;
    QString address;
    QString pubcoin;
    uint creationTime;

    AddressTableEntry() {}
    AddressTableEntry(Type type, const QString &pubcoin):    type(type), pubcoin(pubcoin) {}
    AddressTableEntry(Type type, const QString& label, const QString& address, const uint _creationTime) : type(type), label(label), address(address), creationTime(_creationTime) {}
};

struct AddressTableEntryLessThan {
    bool operator()(const AddressTableEntry& a, const AddressTableEntry& b) const
    {
        return a.address < b.address;
    }
    bool operator()(const AddressTableEntry& a, const QString& b) const
    {
        return a.address < b;
    }
    bool operator()(const QString& a, const AddressTableEntry& b) const
    {
        return a < b.address;
    }
};

/* Determine address type from address purpose */
static AddressTableEntry::Type translateTransactionType(const QString& strPurpose, bool isMine)
{
    AddressTableEntry::Type addressType = AddressTableEntry::Hidden;
    // "refund" addresses aren't shown, and change addresses aren't in mapAddressBook at all.
    if (strPurpose ==  QString::fromStdString(AddressBook::AddressBookPurpose::SEND))
        addressType = AddressTableEntry::Sending;
    else if (strPurpose ==  QString::fromStdString(AddressBook::AddressBookPurpose::RECEIVE))
        addressType = AddressTableEntry::Receiving;
    else if (strPurpose == QString::fromStdString(AddressBook::AddressBookPurpose::DELEGATOR))
        addressType = AddressTableEntry::Delegator;
    else if (strPurpose == QString::fromStdString(AddressBook::AddressBookPurpose::DELEGABLE))
        addressType = AddressTableEntry::Delegable;
    else if (strPurpose == QString::fromStdString(AddressBook::AddressBookPurpose::COLD_STAKING))
        addressType = AddressTableEntry::ColdStaking;
    else if (strPurpose == QString::fromStdString(AddressBook::AddressBookPurpose::COLD_STAKING_SEND))
        addressType = AddressTableEntry::ColdStakingSend;
    else if (strPurpose == QString::fromStdString(AddressBook::AddressBookPurpose::SHIELDED_RECEIVE))
        addressType = AddressTableEntry::ShieldedReceive;
    else if (strPurpose == QString::fromStdString(AddressBook::AddressBookPurpose::SHIELDED_SEND))
        addressType = AddressTableEntry::ShieldedSend;
    else if (strPurpose == "unknown" || strPurpose == "") // if purpose not set, guess
        addressType = (isMine ? AddressTableEntry::Receiving : AddressTableEntry::Sending);
    return addressType;
}

static QString translateTypeToString(AddressTableEntry::Type type)
{
    switch (type) {
        case AddressTableEntry::Sending:
            return QObject::tr("Contact");
        case AddressTableEntry::Receiving:
            return QObject::tr("Receiving");
        case AddressTableEntry::Delegator:
            return QObject::tr("Delegator");
        case AddressTableEntry::Delegable:
            return QObject::tr("Delegable");
        case AddressTableEntry::ColdStaking:
            return QObject::tr("Cold Staking");
        case AddressTableEntry::ColdStakingSend:
            return QObject::tr("Cold Staking Contact");
        case AddressTableEntry::ShieldedReceive:
            return QObject::tr("Receiving Shielded");
        case AddressTableEntry::ShieldedSend:
            return QObject::tr("Contact Shielded");
        case AddressTableEntry::Hidden:
            return QObject::tr("Hidden");
        default:
            return QObject::tr("Unknown");
    }
}

// Private implementation
class AddressTablePriv
{
public:
    CWallet* wallet;
    QList<AddressTableEntry> cachedAddressTable;
    int sendNum = 0;
    int recvNum = 0;
    int dellNum = 0;
    int coldSendNum = 0;
    int shieldedSendNum = 0;
    AddressTableModel* parent;

    AddressTablePriv(CWallet* wallet, AddressTableModel* parent) : wallet(wallet), parent(parent) {}

    void refreshAddressTable()
    {
        cachedAddressTable.clear();
        {
            LOCK(wallet->cs_wallet);
            for (auto it = wallet->NewAddressBookIterator(); it.IsValid(); it.Next()) {
                auto addrBookData = it.GetValue();
{'fraction_non_alphanumeric': 0.10670226477628429, 'fraction_numerical': 0.006076229055422574, 'mean_word_length': 3.9087211929507455, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5033276', 'n_tokens_mistral': 3188, 'n_tokens_neox': 3053, 'n_words': 722}