summaryrefslogtreecommitdiffstats
path: root/application/pages
diff options
context:
space:
mode:
authorPetr Mrázek <peterix@gmail.com>2019-07-30 01:16:56 +0200
committerPetr Mrázek <peterix@gmail.com>2019-07-30 01:16:56 +0200
commit09f7a426abf56f7ff9f874cc36644366f6159fc3 (patch)
tree9530650d96a5299935a61f44e710ab2c5eb81535 /application/pages
parente4fd50e21035046ca576bc87d618cc031776e094 (diff)
downloadMultiMC-09f7a426abf56f7ff9f874cc36644366f6159fc3.tar
MultiMC-09f7a426abf56f7ff9f874cc36644366f6159fc3.tar.gz
MultiMC-09f7a426abf56f7ff9f874cc36644366f6159fc3.tar.lz
MultiMC-09f7a426abf56f7ff9f874cc36644366f6159fc3.tar.xz
MultiMC-09f7a426abf56f7ff9f874cc36644366f6159fc3.zip
GH-2722 GH-2762 Improve mod list sorting
Sorting by version understands version numbers Sorting by name removes 'The' prefixes before sorting
Diffstat (limited to 'application/pages')
-rw-r--r--application/pages/instance/ModFolderPage.cpp60
1 files changed, 59 insertions, 1 deletions
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 <DesktopServices.h>
+#include <QSortFilterProxyModel>
+
+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<SimpleModList *>(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<SimpleModList> 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);