diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index 4c66668e4a..eb0950dae0 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -121,6 +121,7 @@ void Launcher::DataFilesPage::populateFileViews(const QString& contentModelName) for (const QString &path : paths) mSelector->addFiles(path); + mSelector->sortFiles(); PathIterator pathIterator(paths); diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index 3f53a523f4..9cd9f72090 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -149,11 +149,7 @@ std::pair > CS::Editor::readConfi dataDirs.insert (dataDirs.end(), dataLocal.begin(), dataLocal.end()); //iterate the data directories and add them to the file dialog for loading - for (Files::PathContainer::const_reverse_iterator iter = dataDirs.rbegin(); iter != dataDirs.rend(); ++iter) - { - QString path = QString::fromUtf8 (iter->string().c_str()); - mFileDialog.addFiles(path); - } + mFileDialog.addFiles(dataDirs); return std::make_pair (dataDirs, variables["fallback-archive"].as().toStdStringVector()); } diff --git a/apps/opencs/view/doc/filedialog.cpp b/apps/opencs/view/doc/filedialog.cpp index c3d0d8cc50..946dac047e 100644 --- a/apps/opencs/view/doc/filedialog.cpp +++ b/apps/opencs/view/doc/filedialog.cpp @@ -28,9 +28,14 @@ CSVDoc::FileDialog::FileDialog(QWidget *parent) : mAdjusterWidget = new AdjusterWidget (this); } -void CSVDoc::FileDialog::addFiles(const QString &path) +void CSVDoc::FileDialog::addFiles(const std::vector& dataDirs) { - mSelector->addFiles(path); + for (auto iter = dataDirs.rbegin(); iter != dataDirs.rend(); ++iter) + { + QString path = QString::fromUtf8(iter->string().c_str()); + mSelector->addFiles(path); + } + mSelector->sortFiles(); } void CSVDoc::FileDialog::setEncoding(const QString &encoding) diff --git a/apps/opencs/view/doc/filedialog.hpp b/apps/opencs/view/doc/filedialog.hpp index 6c48fa78b9..6a15b46b7c 100644 --- a/apps/opencs/view/doc/filedialog.hpp +++ b/apps/opencs/view/doc/filedialog.hpp @@ -45,7 +45,7 @@ namespace CSVDoc explicit FileDialog(QWidget *parent = nullptr); void showDialog (ContentAction action); - void addFiles (const QString &path); + void addFiles(const std::vector& dataDirs); void setEncoding (const QString &encoding); void clearFiles (); diff --git a/components/contentselector/model/contentmodel.cpp b/components/contentselector/model/contentmodel.cpp index 208b1315f3..ac7851d99c 100644 --- a/components/contentselector/model/contentmodel.cpp +++ b/components/contentselector/model/contentmodel.cpp @@ -2,6 +2,7 @@ #include "esmfile.hpp" #include +#include #include #include @@ -420,6 +421,7 @@ void ContentSelectorModel::ContentModel::addFiles(const QString &path) if (mShowOMWScripts) filters << "*.omwscripts"; dir.setNameFilters(filters); + dir.setSorting(QDir::Name); for (const QString &path2 : dir.entryList()) { @@ -474,8 +476,6 @@ void ContentSelectorModel::ContentModel::addFiles(const QString &path) } } - - sortFiles(); } void ContentSelectorModel::ContentModel::clearFiles() @@ -504,41 +504,37 @@ QStringList ContentSelectorModel::ContentModel::gameFiles() const void ContentSelectorModel::ContentModel::sortFiles() { - //first, sort the model such that all dependencies are ordered upstream (gamefile) first. - bool movedFiles = true; - int fileCount = mFiles.size(); - + emit layoutAboutToBeChanged(); //Dependency sort - //iterate until no sorting of files occurs - while (movedFiles) + std::unordered_set moved; + for(int i = mFiles.size() - 1; i > 0;) { - movedFiles = false; - //iterate each file, obtaining a reference to it's gamefiles list - for (int i = 0; i < fileCount; i++) + const auto file = mFiles.at(i); + if(moved.find(file) == moved.end()) { - QModelIndex idx1 = index (i, 0, QModelIndex()); - const QStringList &gamefiles = mFiles.at(i)->gameFiles(); - //iterate each file after the current file, verifying that none of it's - //dependencies appear. - for (int j = i + 1; j < fileCount; j++) + int index = -1; + for(int j = 0; j < i; ++j) { - if (gamefiles.contains(mFiles.at(j)->fileName(), Qt::CaseInsensitive) - || (!mFiles.at(i)->isGameFile() && gamefiles.isEmpty() - && mFiles.at(j)->fileName().compare("Morrowind.esm", Qt::CaseInsensitive) == 0)) // Hack: implicit dependency on Morrowind.esm for dependency-less files + const QStringList& gameFiles = mFiles.at(j)->gameFiles(); + if(gameFiles.contains(file->fileName(), Qt::CaseInsensitive) + || (!mFiles.at(j)->isGameFile() && gameFiles.isEmpty() + && file->fileName().compare("Morrowind.esm", Qt::CaseInsensitive) == 0)) // Hack: implicit dependency on Morrowind.esm for dependency-less files { - mFiles.move(j, i); - - QModelIndex idx2 = index (j, 0, QModelIndex()); - - emit dataChanged (idx1, idx2); - - movedFiles = true; + index = j; + break; } } - if (movedFiles) - break; + if(index >= 0) + { + mFiles.move(i, index); + moved.insert(file); + continue; + } } + --i; + moved.clear(); } + emit layoutChanged(); } bool ContentSelectorModel::ContentModel::isChecked(const QString& filepath) const diff --git a/components/contentselector/model/contentmodel.hpp b/components/contentselector/model/contentmodel.hpp index f8130e3649..4bbe73b427 100644 --- a/components/contentselector/model/contentmodel.hpp +++ b/components/contentselector/model/contentmodel.hpp @@ -44,6 +44,7 @@ namespace ContentSelectorModel bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override; void addFiles(const QString &path); + void sortFiles(); void clearFiles(); QModelIndex indexFromItem(const EsmFile *item) const; @@ -68,8 +69,6 @@ namespace ContentSelectorModel void addFile(EsmFile *file); - void sortFiles(); - /// Checks a specific plug-in for load order errors /// \return all errors found for specific plug-in QList checkForLoadOrderErrors(const EsmFile *file, int row) const; diff --git a/components/contentselector/view/contentselector.cpp b/components/contentselector/view/contentselector.cpp index f18e80dd0a..ef925148ab 100644 --- a/components/contentselector/view/contentselector.cpp +++ b/components/contentselector/view/contentselector.cpp @@ -173,6 +173,11 @@ void ContentSelectorView::ContentSelector::addFiles(const QString &path) mContentModel->checkForLoadOrderErrors(); } +void ContentSelectorView::ContentSelector::sortFiles() +{ + mContentModel->sortFiles(); +} + void ContentSelectorView::ContentSelector::clearFiles() { mContentModel->clearFiles(); diff --git a/components/contentselector/view/contentselector.hpp b/components/contentselector/view/contentselector.hpp index 4a9983c1bf..b40675bedc 100644 --- a/components/contentselector/view/contentselector.hpp +++ b/components/contentselector/view/contentselector.hpp @@ -28,6 +28,7 @@ namespace ContentSelectorView QString currentFile() const; void addFiles(const QString &path); + void sortFiles(); void clearFiles(); void setProfileContent (const QStringList &fileList);