From 09f7a426abf56f7ff9f874cc36644366f6159fc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Tue, 30 Jul 2019 01:16:56 +0200 Subject: GH-2722 GH-2762 Improve mod list sorting Sorting by version understands version numbers Sorting by name removes 'The' prefixes before sorting --- application/pages/instance/ModFolderPage.cpp | 60 +++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) (limited to 'application/pages') diff --git a/application/pages/instance/ModFolderPage.cpp b/application/pages/instance/ModFolderPage.cpp index 97225832..a04daeb7 100644 --- a/application/pages/instance/ModFolderPage.cpp +++ b/application/pages/instance/ModFolderPage.cpp @@ -32,6 +32,64 @@ #include "minecraft/ComponentList.h" #include +#include + +namespace { + // FIXME: wasteful + void RemoveThePrefix(QString & string) { + QRegularExpression regex(QStringLiteral("^(([Tt][Hh][eE])|([Tt][eE][Hh])) +")); + string.remove(regex); + string = string.trimmed(); + } +} + +class ModSortProxy : public QSortFilterProxyModel +{ +public: + explicit ModSortProxy(QObject *parent = 0) : QSortFilterProxyModel(parent) + { + } + +protected: + bool lessThan(const QModelIndex & source_left, const QModelIndex & source_right) const override + { + SimpleModList *model = qobject_cast(sourceModel()); + if( + !model || + !source_left.isValid() || + !source_right.isValid() || + source_left.column() != source_right.column() + ) { + return QSortFilterProxyModel::lessThan(source_left, source_right); + } + + // we are now guaranteed to have two valid indexes in the same column... we love the provided invariants unconditionally and proceed. + + auto column = (SimpleModList::Columns) source_left.column(); + switch(column) { + // GH-2722 - sort mod names in a way that discards "The" prefixes + case SimpleModList::NameColumn: { + auto dataL = source_left.data(Qt::DisplayRole).toString(); + RemoveThePrefix(dataL); + auto dataR = source_right.data(Qt::DisplayRole).toString(); + RemoveThePrefix(dataR); + + auto less = dataL.compare(dataR, sortCaseSensitivity()) < 0; + return less; + } + // GH-2762 - sort versions by parsing them as versions + case SimpleModList::VersionColumn: { + auto dataL = Version(source_left.data(Qt::DisplayRole).toString()); + auto dataR = Version(source_right.data(Qt::DisplayRole).toString()); + return dataL < dataR; + } + default: { + return QSortFilterProxyModel::lessThan(source_left, source_right); + } + } + } +}; + ModFolderPage::ModFolderPage( BaseInstance *inst, std::shared_ptr mods, @@ -55,7 +113,7 @@ ModFolderPage::ModFolderPage( m_iconName = iconName; m_helpName = helpPage; m_fileSelectionFilter = "%1 (*.zip *.jar)"; - m_filterModel = new QSortFilterProxyModel(this); + m_filterModel = new ModSortProxy(this); m_filterModel->setDynamicSortFilter(true); m_filterModel->setFilterCaseSensitivity(Qt::CaseInsensitive); m_filterModel->setSortCaseSensitivity(Qt::CaseInsensitive); -- cgit v1.2.3