Editor: properly use dynamicsortfilter/optimizations in IdTableProxyModel

This commit is contained in:
Sophia Polfliet
2026-04-09 16:47:02 +00:00
committed by Alexei Kotov
parent 30031dce02
commit 6e98a9e4a8
4 changed files with 13 additions and 33 deletions
+1
View File
@@ -221,6 +221,7 @@ Programmers
sir_herrbatka
smbas
Sophie Kirschner (pineapplemachine)
Sophia Polfliet (Sophie~<3)
spycrab
Stefan Galowicz (bogglez)
Stanislav Bobrov (Jiub)
+11 -25
View File
@@ -6,6 +6,7 @@
#include <QString>
#include <compare>
#include <string_view>
#include <type_traits>
#include <vector>
@@ -19,11 +20,11 @@ class QObject;
namespace
{
std::string getEnumValue(const std::vector<std::pair<int, std::string>>& values, int index)
std::string_view getEnumValue(const std::vector<std::pair<int, std::string>>& values, int index)
{
if (index < 0 || index >= static_cast<int>(values.size()))
{
return "";
return {};
}
return values[index].second;
}
@@ -63,18 +64,17 @@ bool CSMWorld::IdTableProxyModel::filterAcceptsRow(int sourceRow, const QModelIn
CSMWorld::IdTableProxyModel::IdTableProxyModel(QObject* parent)
: QSortFilterProxyModel(parent)
, mFilterTimer{ new QTimer(this) }
, mSourceModel(nullptr)
{
setSortCaseSensitivity(Qt::CaseInsensitive);
mFilterTimer->setSingleShot(true);
mFilterTimer.setSingleShot(true);
int intervalSetting = CSMPrefs::State::get()["ID Tables"]["filter-delay"].toInt();
mFilterTimer->setInterval(intervalSetting);
mFilterTimer.setInterval(intervalSetting);
connect(&CSMPrefs::State::get(), &CSMPrefs::State::settingChanged, this,
[this](const CSMPrefs::Setting* setting) { this->settingChanged(setting); });
connect(mFilterTimer.get(), &QTimer::timeout, this, [this]() { this->timerTimeout(); });
connect(&mFilterTimer, &QTimer::timeout, this, [this]() { this->timerTimeout(); });
}
QModelIndex CSMWorld::IdTableProxyModel::getModelIndex(const std::string& id, int column) const
@@ -97,7 +97,7 @@ void CSMWorld::IdTableProxyModel::setSourceModel(QAbstractItemModel* model)
void CSMWorld::IdTableProxyModel::setFilter(const std::shared_ptr<CSMFilter::Node>& filter)
{
mAwaitingFilter = filter;
mFilterTimer->start();
mFilterTimer.start();
}
bool CSMWorld::IdTableProxyModel::lessThan(const QModelIndex& left, const QModelIndex& right) const
@@ -114,8 +114,8 @@ bool CSMWorld::IdTableProxyModel::lessThan(const QModelIndex& left, const QModel
if (valuesIt != mEnumColumnCache.end())
{
std::string first = getEnumValue(valuesIt->second, left.data().toInt());
std::string second = getEnumValue(valuesIt->second, right.data().toInt());
std::string_view first = getEnumValue(valuesIt->second, left.data().toInt());
std::string_view second = getEnumValue(valuesIt->second, right.data().toInt());
return first < second;
}
return QSortFilterProxyModel::lessThan(left, right);
@@ -129,15 +129,6 @@ QString CSMWorld::IdTableProxyModel::getRecordId(int sourceRow) const
return mSourceModel->data(mSourceModel->index(sourceRow, idColumn)).toString();
}
void CSMWorld::IdTableProxyModel::refreshFilter()
{
if (mFilter)
{
updateColumnMap();
invalidateFilter();
}
}
void CSMWorld::IdTableProxyModel::timerTimeout()
{
if (mAwaitingFilter)
@@ -154,25 +145,20 @@ void CSMWorld::IdTableProxyModel::settingChanged(const CSMPrefs::Setting* settin
{
if (*setting == "ID Tables/filter-delay")
{
mFilterTimer->setInterval(setting->toInt());
mFilterTimer.setInterval(setting->toInt());
}
}
void CSMWorld::IdTableProxyModel::sourceRowsInserted(const QModelIndex& parent, int /*start*/, int end)
{
refreshFilter();
if (!parent.isValid())
{
emit rowAdded(getRecordId(end).toUtf8().constData());
}
}
void CSMWorld::IdTableProxyModel::sourceRowsRemoved(const QModelIndex& /*parent*/, int /*start*/, int /*end*/)
{
refreshFilter();
}
void CSMWorld::IdTableProxyModel::sourceRowsRemoved(const QModelIndex& /*parent*/, int /*start*/, int /*end*/) {}
void CSMWorld::IdTableProxyModel::sourceDataChanged(const QModelIndex& /*topLeft*/, const QModelIndex& /*bottomRight*/)
{
refreshFilter();
}
@@ -32,7 +32,7 @@ namespace CSMWorld
Q_OBJECT
std::shared_ptr<CSMFilter::Node> mFilter;
std::unique_ptr<QTimer> mFilterTimer;
QTimer mFilterTimer;
std::shared_ptr<CSMFilter::Node> mAwaitingFilter;
std::map<int, int> mColumnMap; // column ID, column index in this model (or -1)
@@ -56,8 +56,6 @@ namespace CSMWorld
void setFilter(const std::shared_ptr<CSMFilter::Node>& filter);
void refreshFilter();
protected:
bool lessThan(const QModelIndex& left, const QModelIndex& right) const override;
@@ -81,14 +81,11 @@ int CSMWorld::InfoTableProxyModel::getFirstInfoRow(int currentRow) const
void CSMWorld::InfoTableProxyModel::sourceRowsRemoved(const QModelIndex& /*parent*/, int /*start*/, int /*end*/)
{
refreshFilter();
mFirstRowCache.clear();
}
void CSMWorld::InfoTableProxyModel::sourceRowsInserted(const QModelIndex& parent, int /*start*/, int end)
{
refreshFilter();
if (!parent.isValid())
{
mFirstRowCache.clear();
@@ -100,8 +97,6 @@ void CSMWorld::InfoTableProxyModel::sourceRowsInserted(const QModelIndex& parent
void CSMWorld::InfoTableProxyModel::sourceDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight)
{
refreshFilter();
if (mLastAddedSourceRow != -1 && topLeft.row() <= mLastAddedSourceRow && bottomRight.row() >= mLastAddedSourceRow)
{
// Now the topic of the last added row is set,