Skip to content

Commit

Permalink
Correctly limit overview transaction list
Browse files Browse the repository at this point in the history
The way that the main overview page limits the number
of transactions displayed (currently 5) is not
an appropriate use of Qt. If it's run with a DEBUG
build of Qt, it'll result in a segfault in certain
relatively common situations. Instead of artificially
limiting the rowCount() in the subclassed proxy
filter, we hide/unhide the rows in the displaying
QListView upon any changes in the sorted proxy filter.

Github-Pull: bitcoin-core/gui/pull/704
Rebased-From: 08209c0
  • Loading branch information
john-moffett authored and fanquake committed Feb 2, 2023
1 parent a08353e commit 863cca7
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 25 deletions.
15 changes: 14 additions & 1 deletion src/qt/overviewpage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,6 @@ void OverviewPage::setWalletModel(WalletModel *model)
// Set up transaction list
filter.reset(new TransactionFilterProxy());
filter->setSourceModel(model->getTransactionTableModel());
filter->setLimit(NUM_ITEMS);
filter->setDynamicSortFilter(true);
filter->setSortRole(Qt::EditRole);
filter->setShowInactive(false);
Expand All @@ -273,6 +272,10 @@ void OverviewPage::setWalletModel(WalletModel *model)
ui->listTransactions->setModel(filter.get());
ui->listTransactions->setModelColumn(TransactionTableModel::ToAddress);

connect(filter.get(), &TransactionFilterProxy::rowsInserted, this, &OverviewPage::LimitTransactionRows);
connect(filter.get(), &TransactionFilterProxy::rowsRemoved, this, &OverviewPage::LimitTransactionRows);
connect(filter.get(), &TransactionFilterProxy::rowsMoved, this, &OverviewPage::LimitTransactionRows);
LimitTransactionRows();
// Keep up to date with wallet
setBalance(model->getCachedBalance());
connect(model, &WalletModel::balanceChanged, this, &OverviewPage::setBalance);
Expand Down Expand Up @@ -301,6 +304,16 @@ void OverviewPage::changeEvent(QEvent* e)
QWidget::changeEvent(e);
}

// Only show most recent NUM_ITEMS rows
void OverviewPage::LimitTransactionRows()
{
if (filter && ui->listTransactions && ui->listTransactions->model() && filter.get() == ui->listTransactions->model()) {
for (int i = 0; i < filter->rowCount(); ++i) {
ui->listTransactions->setRowHidden(i, i >= NUM_ITEMS);
}
}
}

void OverviewPage::updateDisplayUnit()
{
if (walletModel && walletModel->getOptionsModel()) {
Expand Down
1 change: 1 addition & 0 deletions src/qt/overviewpage.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ public Q_SLOTS:
std::unique_ptr<TransactionFilterProxy> filter;

private Q_SLOTS:
void LimitTransactionRows();
void updateDisplayUnit();
void handleTransactionClicked(const QModelIndex &index);
void updateAlerts(const QString &warnings);
Expand Down
18 changes: 0 additions & 18 deletions src/qt/transactionfilterproxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ TransactionFilterProxy::TransactionFilterProxy(QObject *parent) :
typeFilter(ALL_TYPES),
watchOnlyFilter(WatchOnlyFilter_All),
minAmount(0),
limitRows(-1),
showInactive(true)
{
}
Expand Down Expand Up @@ -92,25 +91,8 @@ void TransactionFilterProxy::setWatchOnlyFilter(WatchOnlyFilter filter)
invalidateFilter();
}

void TransactionFilterProxy::setLimit(int limit)
{
this->limitRows = limit;
}

void TransactionFilterProxy::setShowInactive(bool _showInactive)
{
this->showInactive = _showInactive;
invalidateFilter();
}

int TransactionFilterProxy::rowCount(const QModelIndex &parent) const
{
if(limitRows != -1)
{
return std::min(QSortFilterProxyModel::rowCount(parent), limitRows);
}
else
{
return QSortFilterProxyModel::rowCount(parent);
}
}
6 changes: 0 additions & 6 deletions src/qt/transactionfilterproxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,9 @@ class TransactionFilterProxy : public QSortFilterProxyModel
void setMinAmount(const CAmount& minimum);
void setWatchOnlyFilter(WatchOnlyFilter filter);

/** Set maximum number of rows returned, -1 if unlimited. */
void setLimit(int limit);

/** Set whether to show conflicted transactions. */
void setShowInactive(bool showInactive);

int rowCount(const QModelIndex &parent = QModelIndex()) const override;

protected:
bool filterAcceptsRow(int source_row, const QModelIndex & source_parent) const override;

Expand All @@ -60,7 +55,6 @@ class TransactionFilterProxy : public QSortFilterProxyModel
quint32 typeFilter;
WatchOnlyFilter watchOnlyFilter;
CAmount minAmount;
int limitRows;
bool showInactive;
};

Expand Down

0 comments on commit 863cca7

Please sign in to comment.