diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp index b888fc43e28..da47befd530 100644 --- a/src/qt/addressbookpage.cpp +++ b/src/qt/addressbookpage.cpp @@ -50,14 +50,21 @@ class AddressBookSortFilterProxyModel final : public QSortFilterProxyModel } auto address = model->index(row, AddressTableModel::Address, parent); + auto addressType = model->index(row, AddressTableModel::Type, parent); #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) const auto pattern = filterRegularExpression(); #else const auto pattern = filterRegExp(); #endif - return (model->data(address).toString().contains(pattern) || - model->data(label).toString().contains(pattern)); + auto filterBy = model->data(address).toString().contains(pattern) || + model->data(label).toString().contains(pattern); + + if (m_type == AddressTableModel::Receive) { + filterBy = filterBy || model->data(addressType).toString().contains(pattern); + } + + return filterBy; } }; @@ -109,11 +116,13 @@ AddressBookPage::AddressBookPage(const PlatformStyle *platformStyle, Mode _mode, ui->labelExplanation->setText(tr("These are your Bitcoin addresses for sending payments. Always check the amount and the receiving address before sending coins.")); ui->deleteAddress->setVisible(true); ui->newAddress->setVisible(true); + ui->searchLineEdit->setPlaceholderText("Enter address or label to search"); break; case ReceivingTab: ui->labelExplanation->setText(tr("These are your Bitcoin addresses for receiving payments. Use the 'Create new receiving address' button in the receive tab to create new addresses.\nSigning is only possible with addresses of the type 'legacy'.")); ui->deleteAddress->setVisible(false); ui->newAddress->setVisible(false); + ui->searchLineEdit->setPlaceholderText("Enter address, address type or label to search"); break; } @@ -156,6 +165,9 @@ void AddressBookPage::setModel(AddressTableModel *_model) // Set column widths ui->tableView->horizontalHeader()->setSectionResizeMode(AddressTableModel::Label, QHeaderView::Stretch); ui->tableView->horizontalHeader()->setSectionResizeMode(AddressTableModel::Address, QHeaderView::ResizeToContents); + ui->tableView->horizontalHeader()->setSectionResizeMode(AddressTableModel::Type, QHeaderView::ResizeToContents); + // Show the "Address type" column only on the Receiving tab + ui->tableView->setColumnHidden(AddressTableModel::ColumnIndex::Type, (tab == SendingTab)); connect(ui->tableView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &AddressBookPage::selectionChanged); @@ -298,6 +310,7 @@ void AddressBookPage::on_exportButton_clicked() // name, column, role writer.setModel(proxyModel); writer.addColumn("Label", AddressTableModel::Label, Qt::EditRole); + writer.addColumn("Address Type", AddressTableModel::Type, Qt::EditRole); writer.addColumn("Address", AddressTableModel::Address, Qt::EditRole); if(!writer.write()) { diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp index e4689e43893..6bb557bd2aa 100644 --- a/src/qt/addresstablemodel.cpp +++ b/src/qt/addresstablemodel.cpp @@ -30,10 +30,13 @@ struct AddressTableEntry Type type; QString label; QString address; + QString addressType; AddressTableEntry() = default; - AddressTableEntry(Type _type, const QString &_label, const QString &_address): - type(_type), label(_label), address(_address) {} + AddressTableEntry(Type _type, const QString &_label, const QString &_address, const OutputType &_addresstype): + type(_type), label(_label), address(_address) { + addressType = GUIUtil::outputTypeDescriptionsMap().at(_addresstype).description; + } }; struct AddressTableEntryLessThan @@ -87,7 +90,8 @@ class AddressTablePriv address.purpose, address.is_mine); cachedAddressTable.append(AddressTableEntry(addressType, QString::fromStdString(address.name), - QString::fromStdString(EncodeDestination(address.dest)))); + QString::fromStdString(EncodeDestination(address.dest)), + wallet.getOutputType(address.dest))); } } // std::lower_bound() and std::upper_bound() require our cachedAddressTable list to be sorted in asc order @@ -96,7 +100,7 @@ class AddressTablePriv std::sort(cachedAddressTable.begin(), cachedAddressTable.end(), AddressTableEntryLessThan()); } - void updateEntry(const QString &address, const QString &label, bool isMine, wallet::AddressPurpose purpose, int status) + void updateEntry(const QString &address, const QString &label, bool isMine, wallet::AddressPurpose purpose, int status, const OutputType &addresstype) { // Find address / label in model QList::iterator lower = std::lower_bound( @@ -117,7 +121,7 @@ class AddressTablePriv break; } parent->beginInsertRows(QModelIndex(), lowerIndex, lowerIndex); - cachedAddressTable.insert(lowerIndex, AddressTableEntry(newEntryType, label, address)); + cachedAddressTable.insert(lowerIndex, AddressTableEntry(newEntryType, label, address, addresstype)); parent->endInsertRows(); break; case CT_UPDATED: @@ -164,7 +168,7 @@ class AddressTablePriv AddressTableModel::AddressTableModel(WalletModel *parent, bool pk_hash_only) : QAbstractTableModel(parent), walletModel(parent) { - columns << tr("Label") << tr("Address"); + columns << tr("Label") << tr("Address Type") << tr("Address"); priv = new AddressTablePriv(this); priv->refreshAddressTable(parent->wallet(), pk_hash_only); } @@ -208,6 +212,8 @@ QVariant AddressTableModel::data(const QModelIndex &index, int role) const } case Address: return rec->address; + case Type: + return rec->addressType; } // no default case, so the compiler can warn about missing cases assert(false); } else if (role == Qt::FontRole) { @@ -216,6 +222,8 @@ QVariant AddressTableModel::data(const QModelIndex &index, int role) const return QFont(); case Address: return GUIUtil::fixedPitchFont(); + case Type: + return QFont(); } // no default case, so the compiler can warn about missing cases assert(false); } else if (role == TypeRole) { @@ -332,11 +340,10 @@ QModelIndex AddressTableModel::index(int row, int column, const QModelIndex &par } } -void AddressTableModel::updateEntry(const QString &address, - const QString &label, bool isMine, wallet::AddressPurpose purpose, int status) +void AddressTableModel::updateEntry(const QString &address, const QString &label, bool isMine, wallet::AddressPurpose purpose, int status, const OutputType &addressType) { // Update address book model from Bitcoin core - priv->updateEntry(address, label, isMine, purpose, status); + priv->updateEntry(address, label, isMine, purpose, status, addressType); } QString AddressTableModel::addRow(const QString &type, const QString &label, const QString &address, const OutputType address_type) diff --git a/src/qt/addresstablemodel.h b/src/qt/addresstablemodel.h index 599aa89cadd..0e0e97e9abc 100644 --- a/src/qt/addresstablemodel.h +++ b/src/qt/addresstablemodel.h @@ -35,7 +35,8 @@ class AddressTableModel : public QAbstractTableModel enum ColumnIndex { Label = 0, /**< User specified label */ - Address = 1 /**< Bitcoin address */ + Type = 1, /**< Address type */ + Address = 2 /**< Bitcoin address */ }; enum RoleIndex { @@ -102,8 +103,7 @@ class AddressTableModel : public QAbstractTableModel public Q_SLOTS: /* Update address list from core. */ - void updateEntry(const QString &address, const QString &label, bool isMine, wallet::AddressPurpose purpose, int status); - + void updateEntry(const QString &address, const QString &label, bool isMine, wallet::AddressPurpose purpose, int status, const OutputType &address_type); friend class AddressTablePriv; }; diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index ee3327530c4..dc2be4cb9d9 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -140,8 +140,10 @@ void WalletModel::updateTransaction() void WalletModel::updateAddressBook(const QString &address, const QString &label, bool isMine, wallet::AddressPurpose purpose, int status) { - if(addressTableModel) - addressTableModel->updateEntry(address, label, isMine, purpose, status); + if (addressTableModel) { + CTxDestination destination = DecodeDestination(address.toStdString()); + addressTableModel->updateEntry(address, label, isMine, purpose, status, m_wallet->getOutputType(destination)); + } } void WalletModel::updateWatchOnlyFlag(bool fHaveWatchonly)