From 9d2bf8af628ad488119e27cabba3c5992c77341b Mon Sep 17 00:00:00 2001 From: Pieter van der Kloet Date: Tue, 7 Jun 2011 01:42:53 +0200 Subject: [PATCH] Added support for the load order of plugins specified in the profiles --- apps/launcher/CMakeLists.txt | 3 ++ apps/launcher/datafilespage.cpp | 34 +++++++++--- apps/launcher/maindialog.cpp | 3 +- apps/launcher/naturalsort.cpp | 95 +++++++++++++++++++++++++++++++++ apps/launcher/naturalsort.hpp | 9 ++++ 5 files changed, 134 insertions(+), 10 deletions(-) create mode 100644 apps/launcher/naturalsort.cpp create mode 100644 apps/launcher/naturalsort.hpp diff --git a/apps/launcher/CMakeLists.txt b/apps/launcher/CMakeLists.txt index db7166af7..598b23fd0 100644 --- a/apps/launcher/CMakeLists.txt +++ b/apps/launcher/CMakeLists.txt @@ -5,6 +5,7 @@ set(LAUNCHER maindialog.cpp playpage.cpp graphicspage.cpp + naturalsort.cpp datafilespage.hpp lineedit.hpp @@ -12,6 +13,7 @@ set(LAUNCHER playpage.hpp combobox.hpp graphicspage.hpp + naturalsort.hpp ) set(MOC_HDRS @@ -21,6 +23,7 @@ set(MOC_HDRS playpage.hpp combobox.hpp graphicspage.hpp + ) find_package(Qt4 REQUIRED) diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index fc27ff7cd..91e165d0b 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -9,6 +9,7 @@ #include "datafilespage.hpp" #include "lineedit.hpp" +#include "naturalsort.hpp" using namespace ESM; using namespace std; @@ -574,19 +575,18 @@ void DataFilesPage::readConfig() mLauncherConfig->beginGroup(profile); QStringList childKeys = mLauncherConfig->childKeys(); + QStringList plugins; + + // Sort the child keys numerical instead of alphabetically + // i.e. Plugin1, Plugin2 instead of Plugin1, Plugin10 + qSort(childKeys.begin(), childKeys.end(), naturalSortLessThanCI); foreach (const QString &key, childKeys) { const QString keyValue = mLauncherConfig->value(key).toString(); if (key.startsWith("Plugin")) { - const QList pluginList = mPluginsModel->findItems(keyValue); - - if (!pluginList.isEmpty()) - { - foreach (const QStandardItem *currentPlugin, pluginList) { - mPluginsModel->setData(currentPlugin->index(), Qt::Checked, Qt::CheckStateRole); - } - } + plugins.append(keyValue); + continue; } if (key.startsWith("Master")) { @@ -600,6 +600,24 @@ void DataFilesPage::readConfig() } } } + + // Iterate over the plugins to set their checkstate and position + for (int i = 0; i < plugins.size(); ++i) { + const QString plugin = plugins.at(i); + + const QList pluginList = mPluginsModel->findItems(plugin); + + if (!pluginList.isEmpty()) + { + foreach (const QStandardItem *currentPlugin, pluginList) { + mPluginsModel->setData(currentPlugin->index(), Qt::Checked, Qt::CheckStateRole); + + // Move the plugin to the position specified in the config file + mPluginsModel->insertRow(i, mPluginsModel->takeRow(currentPlugin->row())); + } + } + } + } void DataFilesPage::writeConfig(QString profile) diff --git a/apps/launcher/maindialog.cpp b/apps/launcher/maindialog.cpp index 51d3a3a0b..96fa3442e 100644 --- a/apps/launcher/maindialog.cpp +++ b/apps/launcher/maindialog.cpp @@ -100,7 +100,6 @@ void MainDialog::createPages() // We can't use QSettings directly because it // does not support multiple keys with the same name QFile file(mGameConfig->fileName()); - qDebug() << "createPages gamefilename: " << mGameConfig->fileName(); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { QMessageBox msgBox; @@ -230,7 +229,7 @@ void MainDialog::play() msgBox.setStandardButtons(QMessageBox::Ok); msgBox.setText(tr("
Could not find OpenMW

\ The OpenMW application is not found.
\ - Please make sure OpenMW is installed and try again.
")); + Please make sure OpenMW is installed correctly and try again.
")); msgBox.exec(); return; diff --git a/apps/launcher/naturalsort.cpp b/apps/launcher/naturalsort.cpp new file mode 100644 index 000000000..648038ed7 --- /dev/null +++ b/apps/launcher/naturalsort.cpp @@ -0,0 +1,95 @@ +/* + * This file contains code found in the QtGui module of the Qt Toolkit. + * See Qt's qfilesystemmodel source files for more information + */ + +#include "naturalsort.hpp" + +static inline QChar getNextChar(const QString &s, int location) +{ + return (location < s.length()) ? s.at(location) : QChar(); +} + +/*! + * Natural number sort, skips spaces. + * + * Examples: + * 1, 2, 10, 55, 100 + * 01.jpg, 2.jpg, 10.jpg + * + * Note on the algorithm: + * Only as many characters as necessary are looked at and at most they all + * are looked at once. + * + * Slower then QString::compare() (of course) + */ +int naturalCompare(const QString &s1, const QString &s2, Qt::CaseSensitivity cs) +{ + for (int l1 = 0, l2 = 0; l1 <= s1.count() && l2 <= s2.count(); ++l1, ++l2) { + // skip spaces, tabs and 0's + QChar c1 = getNextChar(s1, l1); + while (c1.isSpace()) + c1 = getNextChar(s1, ++l1); + QChar c2 = getNextChar(s2, l2); + while (c2.isSpace()) + c2 = getNextChar(s2, ++l2); + + if (c1.isDigit() && c2.isDigit()) { + while (c1.digitValue() == 0) + c1 = getNextChar(s1, ++l1); + while (c2.digitValue() == 0) + c2 = getNextChar(s2, ++l2); + + int lookAheadLocation1 = l1; + int lookAheadLocation2 = l2; + int currentReturnValue = 0; + // find the last digit, setting currentReturnValue as we go if it isn't equal + for ( + QChar lookAhead1 = c1, lookAhead2 = c2; + (lookAheadLocation1 <= s1.length() && lookAheadLocation2 <= s2.length()); + lookAhead1 = getNextChar(s1, ++lookAheadLocation1), + lookAhead2 = getNextChar(s2, ++lookAheadLocation2) + ) { + bool is1ADigit = !lookAhead1.isNull() && lookAhead1.isDigit(); + bool is2ADigit = !lookAhead2.isNull() && lookAhead2.isDigit(); + if (!is1ADigit && !is2ADigit) + break; + if (!is1ADigit) + return -1; + if (!is2ADigit) + return 1; + if (currentReturnValue == 0) { + if (lookAhead1 < lookAhead2) { + currentReturnValue = -1; + } else if (lookAhead1 > lookAhead2) { + currentReturnValue = 1; + } + } + } + if (currentReturnValue != 0) + return currentReturnValue; + } + + if (cs == Qt::CaseInsensitive) { + if (!c1.isLower()) c1 = c1.toLower(); + if (!c2.isLower()) c2 = c2.toLower(); + } + int r = QString::localeAwareCompare(c1, c2); + if (r < 0) + return -1; + if (r > 0) + return 1; + } + // The two strings are the same (02 == 2) so fall back to the normal sort + return QString::compare(s1, s2, cs); +} + +bool naturalSortLessThanCS( const QString &left, const QString &right ) +{ + return (naturalCompare( left, right, Qt::CaseSensitive ) < 0); +} + +bool naturalSortLessThanCI( const QString &left, const QString &right ) +{ + return (naturalCompare( left, right, Qt::CaseInsensitive ) < 0); +} diff --git a/apps/launcher/naturalsort.hpp b/apps/launcher/naturalsort.hpp new file mode 100644 index 000000000..2d314396f --- /dev/null +++ b/apps/launcher/naturalsort.hpp @@ -0,0 +1,9 @@ +#ifndef NATURALSORT_H +#define NATURALSORT_H + +#include + +bool naturalSortLessThanCS( const QString &left, const QString &right ); +bool naturalSortLessThanCI( const QString &left, const QString &right ); + +#endif \ No newline at end of file