Skip to content

Commit 12f9bef

Browse files
gui: Add a combo widget to filter by address type
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.
1 parent 6ff2958 commit 12f9bef

File tree

3 files changed

+75
-4
lines changed

3 files changed

+75
-4
lines changed

src/qt/addressbookpage.cpp

+49-4
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ void AddressBookPage::setModel(AddressTableModel *_model)
173173
return;
174174

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

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

197197
selectionChanged();
198+
199+
this->setupAddressTypeCombo();
198200
}
199201

200202
void AddressBookPage::on_copyAddress_clicked()
@@ -223,7 +225,7 @@ void AddressBookPage::onEditAction()
223225
EditAddressDialog::EditSendingAddress :
224226
EditAddressDialog::EditReceivingAddress, this);
225227
dlg->setModel(model);
226-
QModelIndex origIndex = proxyModel->mapToSource(indexes.at(0));
228+
QModelIndex origIndex = proxyModel->nestedProxyModel()->mapToSource(indexes.at(0));
227229
dlg->loadRow(origIndex.row());
228230
GUIUtil::ShowModalDialogAsynchronously(dlg);
229231
}
@@ -327,7 +329,7 @@ void AddressBookPage::on_exportButton_clicked()
327329
CSVModelWriter writer(filename);
328330

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

352354
void AddressBookPage::selectNewAddress(const QModelIndex &parent, int begin, int /*end*/)
353355
{
354-
QModelIndex idx = proxyModel->mapFromSource(model->index(begin, AddressTableModel::Address, parent));
356+
QModelIndex idx = proxyModel.get()->mapFromSource(model->index(begin, AddressTableModel::Address, parent));
355357
if(idx.isValid() && (idx.data(Qt::EditRole).toString() == newAddressToSelect))
356358
{
357359
// Select row of newly created address, once
@@ -360,3 +362,46 @@ void AddressBookPage::selectNewAddress(const QModelIndex &parent, int begin, int
360362
newAddressToSelect.clear();
361363
}
362364
}
365+
366+
std::map<OutputType, QString> AddressBookPage::addressTypeTooltipMap() {
367+
return {{OutputType::LEGACY, QObject::tr("Not recommended due to higher fees and less protection against typos.")},
368+
{OutputType::P2SH_SEGWIT, QObject::tr("An address compatible with older wallets.")},
369+
{OutputType::BECH32, QObject::tr("Native segwit address (BIP-173). Some old wallets don't support it.")},
370+
{OutputType::BECH32M, QObject::tr("Bech32m (BIP-350) is an upgrade to Bech32, wallet support is still limited.")}};
371+
}
372+
373+
QString AddressBookPage::showAllTypes() const{
374+
return QObject::tr("All");
375+
}
376+
377+
QString AddressBookPage::showAllTypesToolTip() const{
378+
return QObject::tr("Select an address type to filter by.");
379+
}
380+
381+
void AddressBookPage::handleAddressTypeChanged(int index)
382+
{
383+
QString selectedValue = ui->addressType->currentText();
384+
// If show all types is selected then clear the selected value
385+
// that will be sent to the filter so it shows everything
386+
if (selectedValue == showAllTypes()) selectedValue.clear();
387+
// Emit a signal with the selected value
388+
Q_EMIT addressTypeChanged(selectedValue);
389+
}
390+
391+
void AddressBookPage::initializeAddressTypeCombo()
392+
{
393+
const auto index = ui->addressType->count();
394+
ui->addressType->addItem(showAllTypes(), index);
395+
ui->addressType->setItemData(index, showAllTypesToolTip(), Qt::ToolTipRole);
396+
ui->addressType->setCurrentIndex(index);
397+
}
398+
399+
void AddressBookPage::setupAddressTypeCombo()
400+
{
401+
this->initializeAddressTypeCombo();
402+
ui->labelAddressType->setVisible(tab == ReceivingTab);
403+
ui->addressType->setVisible(tab == ReceivingTab);
404+
GUIUtil::AddItemsToAddressTypeCombo(ui->addressType, true, this->addressTypeTooltipMap());
405+
connect(ui->addressType, qOverload<int>(&QComboBox::currentIndexChanged), this, &AddressBookPage::handleAddressTypeChanged);
406+
connect(this, &AddressBookPage::addressTypeChanged, proxyModel->nestedProxyModel(), &QSortFilterProxyModel::setFilterFixedString);
407+
}

src/qt/addressbookpage.h

+16
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
#ifndef BITCOIN_QT_ADDRESSBOOKPAGE_H
66
#define BITCOIN_QT_ADDRESSBOOKPAGE_H
77

8+
#include <outputtype.h>
9+
810
#include <QDialog>
911

1012
class AddressBookSortFilterProxyModel;
@@ -56,6 +58,13 @@ public Q_SLOTS:
5658
std::unique_ptr<AddressBookSortFilterProxyModel> proxyModel{nullptr};
5759
QMenu *contextMenu;
5860
QString newAddressToSelect;
61+
void initializeAddressTypeCombo();
62+
/** Default selected item of the address type combo to display all address types */
63+
QString showAllTypes() const;
64+
QString showAllTypesToolTip() const;
65+
/** Tooltip for each address type that will be displayed on the combo*/
66+
std::map<OutputType, QString> addressTypeTooltipMap();
67+
void setupAddressTypeCombo();
5968

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

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

85101
#endif // BITCOIN_QT_ADDRESSBOOKPAGE_H

src/qt/forms/addressbookpage.ui

+10
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,16 @@
109109
</property>
110110
</widget>
111111
</item>
112+
<item>
113+
<widget class="QLabel" name="labelAddressType">
114+
<property name="text">
115+
<string>Show address type:</string>
116+
</property>
117+
</widget>
118+
</item>
119+
<item>
120+
<widget class="QComboBox" name="addressType"/>
121+
</item>
112122
<item>
113123
<spacer name="horizontalSpacer">
114124
<property name="orientation">

0 commit comments

Comments
 (0)