Skip to content

Commit

Permalink
gui: Add a combo widget to filter by address type
Browse files Browse the repository at this point in the history
Introduce a label and a combobox UI widgets for address type filtering on the address book page.
These 2 widgets are been displayed only on the Receiving tab.
To ensure that the combo box selection updates the filter model correctly, an intermediary signal
(addressTypeChanged) and a slot (handleAddressTypeChanged) were necessary due to the incompatibility
between QComboBox::currentIndexChanged and QSortFilterProxyModel::setFilterFixedString.

Update filter model to use nested filtering so when selected item changes on address type combo
it will update the filter pattern on top of what the parent filter has already, which is lead by the
searchLineEdit widget and all references of the current proxyModel (eg mapToSource, mapFromSource)
to the nested and final filter model.

Use GUIUtil::AddItemsToAddressTypeCombo to populate the combo with the default output types descriptions
passing a defined local map for the output types tooltips that will be displayed for each item,
similarly to the address types combobox in receivecoinsdialog.
  • Loading branch information
pablomartin4btc committed Sep 11, 2023
1 parent 78558de commit a204706
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 4 deletions.
53 changes: 49 additions & 4 deletions src/qt/addressbookpage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ void AddressBookPage::setModel(AddressTableModel *_model)
return;

auto type = tab == ReceivingTab ? AddressTableModel::Receive : AddressTableModel::Send;
proxyModel.reset(new AddressBookSortFilterProxyModel(type, this, false));
proxyModel.reset(new AddressBookSortFilterProxyModel(type, this, true));
proxyModel->setSourceModel(_model);

connect(ui->searchLineEdit, &QLineEdit::textChanged, proxyModel.get(), &QSortFilterProxyModel::setFilterWildcard);
Expand All @@ -195,6 +195,8 @@ void AddressBookPage::setModel(AddressTableModel *_model)
connect(_model, &AddressTableModel::rowsInserted, this, &AddressBookPage::selectNewAddress);

selectionChanged();

this->setupAddressTypeCombo();
}

void AddressBookPage::on_copyAddress_clicked()
Expand Down Expand Up @@ -223,7 +225,7 @@ void AddressBookPage::onEditAction()
EditAddressDialog::EditSendingAddress :
EditAddressDialog::EditReceivingAddress, this);
dlg->setModel(model);
QModelIndex origIndex = proxyModel->mapToSource(indexes.at(0));
QModelIndex origIndex = proxyModel->nestedProxyModel()->mapToSource(indexes.at(0));
dlg->loadRow(origIndex.row());
GUIUtil::ShowModalDialogAsynchronously(dlg);
}
Expand Down Expand Up @@ -327,7 +329,7 @@ void AddressBookPage::on_exportButton_clicked()
CSVModelWriter writer(filename);

// name, column, role
writer.setModel(proxyModel.get());
writer.setModel(proxyModel->nestedProxyModel());
writer.addColumn("Label", AddressTableModel::Label, Qt::EditRole);
writer.addColumn("Address Type", AddressTableModel::Type, Qt::EditRole);
writer.addColumn("Address", AddressTableModel::Address, Qt::EditRole);
Expand All @@ -351,7 +353,7 @@ void AddressBookPage::contextualMenu(const QPoint &point)

void AddressBookPage::selectNewAddress(const QModelIndex &parent, int begin, int /*end*/)
{
QModelIndex idx = proxyModel->mapFromSource(model->index(begin, AddressTableModel::Address, parent));
QModelIndex idx = proxyModel.get()->mapFromSource(model->index(begin, AddressTableModel::Address, parent));
if(idx.isValid() && (idx.data(Qt::EditRole).toString() == newAddressToSelect))
{
// Select row of newly created address, once
Expand All @@ -360,3 +362,46 @@ void AddressBookPage::selectNewAddress(const QModelIndex &parent, int begin, int
newAddressToSelect.clear();
}
}

std::map<OutputType, QString> AddressBookPage::addressTypeTooltipMap() {
return {{OutputType::LEGACY, QObject::tr("Not recommended due to higher fees and less protection against typos.")},
{OutputType::P2SH_SEGWIT, QObject::tr("An address compatible with older wallets.")},
{OutputType::BECH32, QObject::tr("Native segwit address (BIP-173). Some old wallets don't support it.")},
{OutputType::BECH32M, QObject::tr("Bech32m (BIP-350) is an upgrade to Bech32, wallet support is still limited.")}};
}

QString AddressBookPage::showAllTypes() const{
return QObject::tr("All");
}

QString AddressBookPage::showAllTypesToolTip() const{
return QObject::tr("Select an address type to filter by.");
}

void AddressBookPage::handleAddressTypeChanged(int index)
{
QString selectedValue = ui->addressType->currentText();
// If show all types is selected then clear the selected value
// that will be sent to the filter so it shows everything
if (selectedValue == showAllTypes()) selectedValue.clear();
// Emit a signal with the selected value
Q_EMIT addressTypeChanged(selectedValue);
}

void AddressBookPage::initializeAddressTypeCombo()
{
const auto index = ui->addressType->count();
ui->addressType->addItem(showAllTypes(), index);
ui->addressType->setItemData(index, showAllTypesToolTip(), Qt::ToolTipRole);
ui->addressType->setCurrentIndex(index);
}

void AddressBookPage::setupAddressTypeCombo()
{
this->initializeAddressTypeCombo();
ui->labelAddressType->setVisible(tab == ReceivingTab);
ui->addressType->setVisible(tab == ReceivingTab);
GUIUtil::AddItemsToAddressTypeCombo(ui->addressType, true, this->addressTypeTooltipMap());
connect(ui->addressType, qOverload<int>(&QComboBox::currentIndexChanged), this, &AddressBookPage::handleAddressTypeChanged);
connect(this, &AddressBookPage::addressTypeChanged, proxyModel->nestedProxyModel(), &QSortFilterProxyModel::setFilterFixedString);
}
16 changes: 16 additions & 0 deletions src/qt/addressbookpage.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#ifndef BITCOIN_QT_ADDRESSBOOKPAGE_H
#define BITCOIN_QT_ADDRESSBOOKPAGE_H

#include <outputtype.h>

#include <QDialog>

class AddressBookSortFilterProxyModel;
Expand Down Expand Up @@ -56,6 +58,13 @@ public Q_SLOTS:
std::unique_ptr<AddressBookSortFilterProxyModel> proxyModel{nullptr};
QMenu *contextMenu;
QString newAddressToSelect;
void initializeAddressTypeCombo();
/** Default selected item of the address type combo to display all address types */
QString showAllTypes() const;
QString showAllTypesToolTip() const;
/** Tooltip for each address type that will be displayed on the combo*/
std::map<OutputType, QString> addressTypeTooltipMap();
void setupAddressTypeCombo();

private Q_SLOTS:
/** Delete currently selected address entry */
Expand All @@ -77,9 +86,16 @@ private Q_SLOTS:
void contextualMenu(const QPoint &point);
/** New entry/entries were added to address table */
void selectNewAddress(const QModelIndex &parent, int begin, int /*end*/);
/** Address type combo selection changed */
void handleAddressTypeChanged(int index);

Q_SIGNALS:
void sendCoins(QString addr);
/** Emitted when the addressType combobox is changed (handled by handleAddressTypeChange).
* This signal is used as a workaround to connect the combobox and the proxy model filter,
* preventing the compiler error "Signal and slot arguments are not compatible."*/
void addressTypeChanged(const QString &addressType);

};

#endif // BITCOIN_QT_ADDRESSBOOKPAGE_H
10 changes: 10 additions & 0 deletions src/qt/forms/addressbookpage.ui
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,16 @@
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="labelAddressType">
<property name="text">
<string>Show address type:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="addressType"/>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
Expand Down

0 comments on commit a204706

Please sign in to comment.