bitcoin/src/qt/transactionfilterproxy.cpp
John Moffett b7e242ecb3
Correctly limit overview transaction list
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: 08209c039f
2023-02-20 17:15:38 +00:00

98 lines
3 KiB
C++

// Copyright (c) 2011-2021 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <qt/transactionfilterproxy.h>
#include <qt/transactiontablemodel.h>
#include <qt/transactionrecord.h>
#include <algorithm>
#include <cstdlib>
#include <optional>
TransactionFilterProxy::TransactionFilterProxy(QObject *parent) :
QSortFilterProxyModel(parent),
m_search_string(),
typeFilter(ALL_TYPES),
watchOnlyFilter(WatchOnlyFilter_All),
minAmount(0),
showInactive(true)
{
}
bool TransactionFilterProxy::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
{
QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
int status = index.data(TransactionTableModel::StatusRole).toInt();
if (!showInactive && status == TransactionStatus::Conflicted)
return false;
int type = index.data(TransactionTableModel::TypeRole).toInt();
if (!(TYPE(type) & typeFilter))
return false;
bool involvesWatchAddress = index.data(TransactionTableModel::WatchonlyRole).toBool();
if (involvesWatchAddress && watchOnlyFilter == WatchOnlyFilter_No)
return false;
if (!involvesWatchAddress && watchOnlyFilter == WatchOnlyFilter_Yes)
return false;
QDateTime datetime = index.data(TransactionTableModel::DateRole).toDateTime();
if (dateFrom && datetime < *dateFrom) return false;
if (dateTo && datetime > *dateTo) return false;
QString address = index.data(TransactionTableModel::AddressRole).toString();
QString label = index.data(TransactionTableModel::LabelRole).toString();
QString txid = index.data(TransactionTableModel::TxHashRole).toString();
if (!address.contains(m_search_string, Qt::CaseInsensitive) &&
! label.contains(m_search_string, Qt::CaseInsensitive) &&
! txid.contains(m_search_string, Qt::CaseInsensitive)) {
return false;
}
qint64 amount = llabs(index.data(TransactionTableModel::AmountRole).toLongLong());
if (amount < minAmount)
return false;
return true;
}
void TransactionFilterProxy::setDateRange(const std::optional<QDateTime>& from, const std::optional<QDateTime>& to)
{
dateFrom = from;
dateTo = to;
invalidateFilter();
}
void TransactionFilterProxy::setSearchString(const QString &search_string)
{
if (m_search_string == search_string) return;
m_search_string = search_string;
invalidateFilter();
}
void TransactionFilterProxy::setTypeFilter(quint32 modes)
{
this->typeFilter = modes;
invalidateFilter();
}
void TransactionFilterProxy::setMinAmount(const CAmount& minimum)
{
this->minAmount = minimum;
invalidateFilter();
}
void TransactionFilterProxy::setWatchOnlyFilter(WatchOnlyFilter filter)
{
this->watchOnlyFilter = filter;
invalidateFilter();
}
void TransactionFilterProxy::setShowInactive(bool _showInactive)
{
this->showInactive = _showInactive;
invalidateFilter();
}