summaryrefslogtreecommitdiff
path: root/src/modinfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/modinfo.cpp')
-rw-r--r--src/modinfo.cpp498
1 files changed, 267 insertions, 231 deletions
diff --git a/src/modinfo.cpp b/src/modinfo.cpp
index 0b9d65f8..c14eedb7 100644
--- a/src/modinfo.cpp
+++ b/src/modinfo.cpp
@@ -20,22 +20,22 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "modinfo.h"
#include "modinfobackup.h"
+#include "modinforegular.h"
#include "modinfoforeign.h"
#include "modinfooverwrite.h"
-#include "modinforegular.h"
-#include "categories.h"
-#include "filenamestring.h"
#include "installationtester.h"
+#include "categories.h"
#include "modinfodialog.h"
#include "overwriteinfodialog.h"
+#include "filenamestring.h"
#include "versioninfo.h"
-#include <appconfig.h>
#include <iplugingame.h>
+#include <versioninfo.h>
+#include <appconfig.h>
#include <scriptextender.h>
#include <unmanagedmods.h>
-#include <versioninfo.h>
#include <QApplication>
#include <QDirIterator>
@@ -45,317 +45,353 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
using namespace MOBase;
using namespace MOShared;
+
std::vector<ModInfo::Ptr> ModInfo::s_Collection;
std::map<QString, unsigned int> ModInfo::s_ModsByName;
-std::map<int, std::vector<unsigned int>> ModInfo::s_ModsByModID;
+std::map<int, std::vector<unsigned int> > ModInfo::s_ModsByModID;
int ModInfo::s_NextID;
QMutex ModInfo::s_Mutex(QMutex::Recursive);
QString ModInfo::s_HiddenExt(".mohidden");
-static bool ByName(const ModInfo::Ptr& LHS, const ModInfo::Ptr& RHS) {
- return QString::compare(LHS->name(), RHS->name(), Qt::CaseInsensitive) < 0;
+
+static bool ByName(const ModInfo::Ptr &LHS, const ModInfo::Ptr &RHS)
+{
+ return QString::compare(LHS->name(), RHS->name(), Qt::CaseInsensitive) < 0;
}
-ModInfo::Ptr ModInfo::createFrom(const QDir& dir, DirectoryEntry** directoryStructure) {
- QMutexLocker locker(&s_Mutex);
- // int id = s_NextID++;
- static QRegExp backupExp(".*backup[0-9]*");
- ModInfo::Ptr result;
- if (backupExp.exactMatch(dir.dirName())) {
- result = ModInfo::Ptr(new ModInfoBackup(dir, directoryStructure));
- } else {
- result = ModInfo::Ptr(new ModInfoRegular(dir, directoryStructure));
- }
- s_Collection.push_back(result);
- return result;
+
+ModInfo::Ptr ModInfo::createFrom(const QDir &dir, DirectoryEntry **directoryStructure)
+{
+ QMutexLocker locker(&s_Mutex);
+// int id = s_NextID++;
+ static QRegExp backupExp(".*backup[0-9]*");
+ ModInfo::Ptr result;
+ if (backupExp.exactMatch(dir.dirName())) {
+ result = ModInfo::Ptr(new ModInfoBackup(dir, directoryStructure));
+ } else {
+ result = ModInfo::Ptr(new ModInfoRegular(dir, directoryStructure));
+ }
+ s_Collection.push_back(result);
+ return result;
}
-ModInfo::Ptr ModInfo::createFromPlugin(const QString& modName, const QString& espName, const QStringList& bsaNames,
- ModInfo::EModType modType, DirectoryEntry** directoryStructure) {
- QMutexLocker locker(&s_Mutex);
- ModInfo::Ptr result = ModInfo::Ptr(new ModInfoForeign(modName, espName, bsaNames, modType, directoryStructure));
- s_Collection.push_back(result);
- return result;
+ModInfo::Ptr ModInfo::createFromPlugin(const QString &modName,
+ const QString &espName,
+ const QStringList &bsaNames,
+ ModInfo::EModType modType,
+ DirectoryEntry **directoryStructure) {
+ QMutexLocker locker(&s_Mutex);
+ ModInfo::Ptr result = ModInfo::Ptr(
+ new ModInfoForeign(modName, espName, bsaNames, modType, directoryStructure));
+ s_Collection.push_back(result);
+ return result;
}
-QString ModInfo::getContentTypeName(int contentType) {
- switch (contentType) {
- case CONTENT_PLUGIN:
- return tr("Plugins");
- case CONTENT_TEXTURE:
- return tr("Textures");
- case CONTENT_MESH:
- return tr("Meshes");
- case CONTENT_BSA:
- return tr("Bethesda Archive");
- case CONTENT_INTERFACE:
- return tr("UI Changes");
- case CONTENT_SOUND:
- return tr("Sound Effects");
- case CONTENT_SCRIPT:
- return tr("Scripts");
- case CONTENT_SKSE:
- return tr("SKSE Plugins");
- case CONTENT_SKYPROC:
- return tr("SkyProc Tools");
- case CONTENT_MCM:
- return tr("MCM Data");
- default:
- throw MyException(tr("invalid content type %1").arg(contentType));
- }
+QString ModInfo::getContentTypeName(int contentType)
+{
+ switch (contentType) {
+ case CONTENT_PLUGIN: return tr("Plugins");
+ case CONTENT_TEXTURE: return tr("Textures");
+ case CONTENT_MESH: return tr("Meshes");
+ case CONTENT_BSA: return tr("Bethesda Archive");
+ case CONTENT_INTERFACE: return tr("UI Changes");
+ case CONTENT_SOUND: return tr("Sound Effects");
+ case CONTENT_SCRIPT: return tr("Scripts");
+ case CONTENT_SKSE: return tr("SKSE Plugins");
+ case CONTENT_SKYPROC: return tr("SkyProc Tools");
+ case CONTENT_MCM: return tr("MCM Data");
+ default: throw MyException(tr("invalid content type %1").arg(contentType));
+ }
}
-void ModInfo::createFromOverwrite() {
- QMutexLocker locker(&s_Mutex);
+void ModInfo::createFromOverwrite()
+{
+ QMutexLocker locker(&s_Mutex);
- s_Collection.push_back(ModInfo::Ptr(new ModInfoOverwrite));
+ s_Collection.push_back(ModInfo::Ptr(new ModInfoOverwrite));
}
-unsigned int ModInfo::getNumMods() {
- QMutexLocker locker(&s_Mutex);
- return static_cast<unsigned int>(s_Collection.size());
+unsigned int ModInfo::getNumMods()
+{
+ QMutexLocker locker(&s_Mutex);
+ return static_cast<unsigned int>(s_Collection.size());
}
-ModInfo::Ptr ModInfo::getByIndex(unsigned int index) {
- QMutexLocker locker(&s_Mutex);
- if (index >= s_Collection.size() && index != ULONG_MAX) {
- throw MyException(tr("invalid mod index %1").arg(index));
- }
- if (index == ULONG_MAX)
- return s_Collection[ModInfo::getIndex("Overwrite")];
- return s_Collection[index];
+ModInfo::Ptr ModInfo::getByIndex(unsigned int index)
+{
+ QMutexLocker locker(&s_Mutex);
+
+ if (index >= s_Collection.size() && index != ULONG_MAX) {
+ throw MyException(tr("invalid mod index %1").arg(index));
+ }
+ if (index == ULONG_MAX) return s_Collection[ModInfo::getIndex("Overwrite")];
+ return s_Collection[index];
}
-std::vector<ModInfo::Ptr> ModInfo::getByModID(int modID) {
- QMutexLocker locker(&s_Mutex);
- auto iter = s_ModsByModID.find(modID);
- if (iter == s_ModsByModID.end()) {
- return std::vector<ModInfo::Ptr>();
- }
+std::vector<ModInfo::Ptr> ModInfo::getByModID(int modID)
+{
+ QMutexLocker locker(&s_Mutex);
- std::vector<ModInfo::Ptr> result;
- for (auto idxIter = iter->second.begin(); idxIter != iter->second.end(); ++idxIter) {
- result.push_back(getByIndex(*idxIter));
- }
+ auto iter = s_ModsByModID.find(modID);
+ if (iter == s_ModsByModID.end()) {
+ return std::vector<ModInfo::Ptr>();
+ }
+
+ std::vector<ModInfo::Ptr> result;
+ for (auto idxIter = iter->second.begin(); idxIter != iter->second.end(); ++idxIter) {
+ result.push_back(getByIndex(*idxIter));
+ }
- return result;
+ return result;
}
-bool ModInfo::removeMod(unsigned int index) {
- QMutexLocker locker(&s_Mutex);
- if (index >= s_Collection.size()) {
- throw MyException(tr("remove: invalid mod index %1").arg(index));
- }
- // update the indices first
- ModInfo::Ptr modInfo = s_Collection[index];
- s_ModsByName.erase(s_ModsByName.find(modInfo->name()));
+bool ModInfo::removeMod(unsigned int index)
+{
+ QMutexLocker locker(&s_Mutex);
- auto iter = s_ModsByModID.find(modInfo->getNexusID());
- if (iter != s_ModsByModID.end()) {
- std::vector<unsigned int> indices = iter->second;
- indices.erase(std::remove(indices.begin(), indices.end(), index), indices.end());
- s_ModsByModID[modInfo->getNexusID()] = indices;
- }
+ if (index >= s_Collection.size()) {
+ throw MyException(tr("remove: invalid mod index %1").arg(index));
+ }
+ // update the indices first
+ ModInfo::Ptr modInfo = s_Collection[index];
+ s_ModsByName.erase(s_ModsByName.find(modInfo->name()));
+
+ auto iter = s_ModsByModID.find(modInfo->getNexusID());
+ if (iter != s_ModsByModID.end()) {
+ std::vector<unsigned int> indices = iter->second;
+ indices.erase(std::remove(indices.begin(), indices.end(), index), indices.end());
+ s_ModsByModID[modInfo->getNexusID()] = indices;
+ }
- // physically remove the mod directory
- // TODO the return value is ignored because the indices were already removed here, so stopping
- // would cause data inconsistencies. Instead we go through with the removal but the mod will show up
- // again if the user refreshes
- modInfo->remove();
+ // physically remove the mod directory
+ //TODO the return value is ignored because the indices were already removed here, so stopping
+ // would cause data inconsistencies. Instead we go through with the removal but the mod will show up
+ // again if the user refreshes
+ modInfo->remove();
- // finally, remove the mod from the collection
- s_Collection.erase(s_Collection.begin() + index);
+ // finally, remove the mod from the collection
+ s_Collection.erase(s_Collection.begin() + index);
- // and update the indices
- updateIndices();
- return true;
+ // and update the indices
+ updateIndices();
+ return true;
}
-unsigned int ModInfo::getIndex(const QString& name) {
- QMutexLocker locker(&s_Mutex);
- std::map<QString, unsigned int>::iterator iter = s_ModsByName.find(name);
- if (iter == s_ModsByName.end()) {
- return UINT_MAX;
- }
+unsigned int ModInfo::getIndex(const QString &name)
+{
+ QMutexLocker locker(&s_Mutex);
+
+ std::map<QString, unsigned int>::iterator iter = s_ModsByName.find(name);
+ if (iter == s_ModsByName.end()) {
+ return UINT_MAX;
+ }
- return iter->second;
+ return iter->second;
}
-unsigned int ModInfo::findMod(const boost::function<bool(ModInfo::Ptr)>& filter) {
- for (unsigned int i = 0U; i < s_Collection.size(); ++i) {
- if (filter(s_Collection[i])) {
- return i;
- }
+unsigned int ModInfo::findMod(const boost::function<bool (ModInfo::Ptr)> &filter)
+{
+ for (unsigned int i = 0U; i < s_Collection.size(); ++i) {
+ if (filter(s_Collection[i])) {
+ return i;
}
- return UINT_MAX;
+ }
+ return UINT_MAX;
}
-void ModInfo::updateFromDisc(const QString& modDirectory, DirectoryEntry** directoryStructure, bool displayForeign,
- MOBase::IPluginGame const* game) {
- QMutexLocker lock(&s_Mutex);
- s_Collection.clear();
- s_NextID = 0;
- { // list all directories in the mod directory and make a mod out of each
- QDir mods(QDir::fromNativeSeparators(modDirectory));
- mods.setFilter(QDir::Dirs | QDir::NoDotAndDotDot);
- QDirIterator modIter(mods);
- while (modIter.hasNext()) {
- createFrom(QDir(modIter.next()), directoryStructure);
- }
+void ModInfo::updateFromDisc(const QString &modDirectory,
+ DirectoryEntry **directoryStructure,
+ bool displayForeign,
+ MOBase::IPluginGame const *game)
+{
+ QMutexLocker lock(&s_Mutex);
+ s_Collection.clear();
+ s_NextID = 0;
+
+ { // list all directories in the mod directory and make a mod out of each
+ QDir mods(QDir::fromNativeSeparators(modDirectory));
+ mods.setFilter(QDir::Dirs | QDir::NoDotAndDotDot);
+ QDirIterator modIter(mods);
+ while (modIter.hasNext()) {
+ createFrom(QDir(modIter.next()), directoryStructure);
}
+ }
- UnmanagedMods* unmanaged = game->feature<UnmanagedMods>();
- if (unmanaged != nullptr) {
- for (const QString& modName : unmanaged->mods(!displayForeign)) {
- ModInfo::EModType modType =
- game->DLCPlugins().contains(unmanaged->referenceFile(modName).fileName(), Qt::CaseInsensitive)
- ? ModInfo::EModType::MOD_DLC
- : (game->CCPlugins().contains(unmanaged->referenceFile(modName).fileName(), Qt::CaseInsensitive)
- ? ModInfo::EModType::MOD_CC
- : ModInfo::EModType::MOD_DEFAULT);
+ UnmanagedMods *unmanaged = game->feature<UnmanagedMods>();
+ if (unmanaged != nullptr) {
+ for (const QString &modName : unmanaged->mods(!displayForeign)) {
+ ModInfo::EModType modType = game->DLCPlugins().contains(unmanaged->referenceFile(modName).fileName(), Qt::CaseInsensitive) ? ModInfo::EModType::MOD_DLC :
+ (game->CCPlugins().contains(unmanaged->referenceFile(modName).fileName(), Qt::CaseInsensitive) ? ModInfo::EModType::MOD_CC : ModInfo::EModType::MOD_DEFAULT);
- createFromPlugin(unmanaged->displayName(modName), unmanaged->referenceFile(modName).absoluteFilePath(),
- unmanaged->secondaryFiles(modName), modType, directoryStructure);
- }
+ createFromPlugin(unmanaged->displayName(modName),
+ unmanaged->referenceFile(modName).absoluteFilePath(),
+ unmanaged->secondaryFiles(modName),
+ modType,
+ directoryStructure);
}
+ }
- createFromOverwrite();
+ createFromOverwrite();
- std::sort(s_Collection.begin(), s_Collection.end(), ByName);
+ std::sort(s_Collection.begin(), s_Collection.end(), ByName);
- updateIndices();
+ updateIndices();
}
-void ModInfo::updateIndices() {
- s_ModsByName.clear();
- s_ModsByModID.clear();
- for (unsigned int i = 0; i < s_Collection.size(); ++i) {
- QString modName = s_Collection[i]->internalName();
- int modID = s_Collection[i]->getNexusID();
- s_ModsByName[modName] = i;
- s_ModsByModID[modID].push_back(i);
- }
+void ModInfo::updateIndices()
+{
+ s_ModsByName.clear();
+ s_ModsByModID.clear();
+
+ for (unsigned int i = 0; i < s_Collection.size(); ++i) {
+ QString modName = s_Collection[i]->internalName();
+ int modID = s_Collection[i]->getNexusID();
+ s_ModsByName[modName] = i;
+ s_ModsByModID[modID].push_back(i);
+ }
}
-ModInfo::ModInfo() : m_Valid(false), m_PrimaryCategory(-1) {}
-void ModInfo::checkChunkForUpdate(const std::vector<int>& modIDs, QObject* receiver) {
- if (modIDs.size() != 0) {
- NexusInterface::instance()->requestUpdates(modIDs, receiver, QVariant(), QString());
- }
+ModInfo::ModInfo()
+ : m_Valid(false), m_PrimaryCategory(-1)
+{
+}
+
+
+void ModInfo::checkChunkForUpdate(const std::vector<int> &modIDs, QObject *receiver)
+{
+ if (modIDs.size() != 0) {
+ NexusInterface::instance()->requestUpdates(modIDs, receiver, QVariant(), QString());
+ }
}
-int ModInfo::checkAllForUpdate(QObject* receiver) {
- // technically this should be 255 but those requests can take nexus fairly long, produce
- // large output and may have been the cause of issue #1166
- static const int chunkSize = 64;
- int result = 0;
- std::vector<int> modIDs;
+int ModInfo::checkAllForUpdate(QObject *receiver)
+{
+ // technically this should be 255 but those requests can take nexus fairly long, produce
+ // large output and may have been the cause of issue #1166
+ static const int chunkSize = 64;
+
+ int result = 0;
+ std::vector<int> modIDs;
- // I ought to store this, it's used elsewhere
- IPluginGame const* game = qApp->property("managed_game").value<IPluginGame*>();
+ //I ought to store this, it's used elsewhere
+ IPluginGame const *game = qApp->property("managed_game").value<IPluginGame *>();
- modIDs.push_back(game->nexusModOrganizerID());
+ modIDs.push_back(game->nexusModOrganizerID());
- for (const ModInfo::Ptr& mod : s_Collection) {
- if (mod->canBeUpdated()) {
- modIDs.push_back(mod->getNexusID());
- if (modIDs.size() >= chunkSize) {
- checkChunkForUpdate(modIDs, receiver);
- modIDs.clear();
- }
- }
+ for (const ModInfo::Ptr &mod : s_Collection) {
+ if (mod->canBeUpdated()) {
+ modIDs.push_back(mod->getNexusID());
+ if (modIDs.size() >= chunkSize) {
+ checkChunkForUpdate(modIDs, receiver);
+ modIDs.clear();
+ }
}
+ }
- checkChunkForUpdate(modIDs, receiver);
+ checkChunkForUpdate(modIDs, receiver);
- return result;
+ return result;
}
-void ModInfo::setVersion(const VersionInfo& version) { m_Version = version; }
+void ModInfo::setVersion(const VersionInfo &version)
+{
+ m_Version = version;
+}
-void ModInfo::setPluginSelected(const bool& isSelected) { m_PluginSelected = isSelected; }
+void ModInfo::setPluginSelected(const bool &isSelected)
+{
+ m_PluginSelected = isSelected;
+}
-void ModInfo::addCategory(const QString& categoryName) {
- int id = CategoryFactory::instance().getCategoryID(categoryName);
- if (id == -1) {
- id = CategoryFactory::instance().addCategory(categoryName, std::vector<int>(), 0);
- }
- setCategory(id, true);
+void ModInfo::addCategory(const QString &categoryName)
+{
+ int id = CategoryFactory::instance().getCategoryID(categoryName);
+ if (id == -1) {
+ id = CategoryFactory::instance().addCategory(categoryName, std::vector<int>(), 0);
+ }
+ setCategory(id, true);
}
-bool ModInfo::removeCategory(const QString& categoryName) {
- int id = CategoryFactory::instance().getCategoryID(categoryName);
- if (id == -1) {
- return false;
- }
- if (!categorySet(id)) {
- return false;
- }
- setCategory(id, false);
- return true;
+bool ModInfo::removeCategory(const QString &categoryName)
+{
+ int id = CategoryFactory::instance().getCategoryID(categoryName);
+ if (id == -1) {
+ return false;
+ }
+ if (!categorySet(id)) {
+ return false;
+ }
+ setCategory(id, false);
+ return true;
}
-QStringList ModInfo::categories() {
- QStringList result;
+QStringList ModInfo::categories()
+{
+ QStringList result;
- CategoryFactory& catFac = CategoryFactory::instance();
- for (int id : m_Categories) {
- result.append(catFac.getCategoryName(catFac.getCategoryIndex(id)));
- }
+ CategoryFactory &catFac = CategoryFactory::instance();
+ for (int id : m_Categories) {
+ result.append(catFac.getCategoryName(catFac.getCategoryIndex(id)));
+ }
- return result;
+ return result;
}
-bool ModInfo::hasFlag(ModInfo::EFlag flag) const {
- std::vector<EFlag> flags = getFlags();
- return std::find(flags.begin(), flags.end(), flag) != flags.end();
+bool ModInfo::hasFlag(ModInfo::EFlag flag) const
+{
+ std::vector<EFlag> flags = getFlags();
+ return std::find(flags.begin(), flags.end(), flag) != flags.end();
}
-bool ModInfo::hasContent(ModInfo::EContent content) const {
- std::vector<EContent> contents = getContents();
- return std::find(contents.begin(), contents.end(), content) != contents.end();
+bool ModInfo::hasContent(ModInfo::EContent content) const
+{
+ std::vector<EContent> contents = getContents();
+ return std::find(contents.begin(), contents.end(), content) != contents.end();
}
-bool ModInfo::categorySet(int categoryID) const {
- for (std::set<int>::const_iterator iter = m_Categories.begin(); iter != m_Categories.end(); ++iter) {
- if ((*iter == categoryID) || (CategoryFactory::instance().isDecendantOf(*iter, categoryID))) {
- return true;
- }
+bool ModInfo::categorySet(int categoryID) const
+{
+ for (std::set<int>::const_iterator iter = m_Categories.begin(); iter != m_Categories.end(); ++iter) {
+ if ((*iter == categoryID) ||
+ (CategoryFactory::instance().isDecendantOf(*iter, categoryID))) {
+ return true;
}
+ }
- return false;
+ return false;
}
-void ModInfo::testValid() {
- m_Valid = false;
- QDirIterator dirIter(absolutePath());
- while (dirIter.hasNext()) {
- dirIter.next();
- if (dirIter.fileInfo().isDir()) {
- if (InstallationTester::isTopLevelDirectory(dirIter.fileName())) {
- m_Valid = true;
- break;
- }
- } else {
- if (InstallationTester::isTopLevelSuffix(dirIter.fileName())) {
- m_Valid = true;
- break;
- }
- }
+void ModInfo::testValid()
+{
+ m_Valid = false;
+ QDirIterator dirIter(absolutePath());
+ while (dirIter.hasNext()) {
+ dirIter.next();
+ if (dirIter.fileInfo().isDir()) {
+ if (InstallationTester::isTopLevelDirectory(dirIter.fileName())) {
+ m_Valid = true;
+ break;
+ }
+ } else {
+ if (InstallationTester::isTopLevelSuffix(dirIter.fileName())) {
+ m_Valid = true;
+ break;
+ }
}
+ }
- // NOTE: in Qt 4.7 it seems that QDirIterator leaves a file handle open if it is not iterated to the
- // end
- while (dirIter.hasNext()) {
- dirIter.next();
- }
+ // NOTE: in Qt 4.7 it seems that QDirIterator leaves a file handle open if it is not iterated to the
+ // end
+ while (dirIter.hasNext()) {
+ dirIter.next();
+ }
}