From b0e3e86a61770c3d6c18161b05c745f30f1a2cb3 Mon Sep 17 00:00:00 2001 From: Tannin Date: Fri, 6 May 2016 23:39:08 +0200 Subject: moved plugins.txt reading/writing to game plugin --- src/pluginlist.cpp | 285 +++++++++++++++-------------------------------------- 1 file changed, 82 insertions(+), 203 deletions(-) (limited to 'src/pluginlist.cpp') diff --git a/src/pluginlist.cpp b/src/pluginlist.cpp index bf5a09dc..8110cdf2 100644 --- a/src/pluginlist.cpp +++ b/src/pluginlist.cpp @@ -20,7 +20,6 @@ along with Mod Organizer. If not, see . #include "pluginlist.h" #include "inject.h" #include "settings.h" -#include "safewritefile.h" #include "scopeguard.h" #include "modinfo.h" #include @@ -28,6 +27,8 @@ along with Mod Organizer. If not, see . #include #include #include +#include +#include #include #include @@ -74,14 +75,6 @@ PluginList::PluginList(QObject *parent) : QAbstractItemModel(parent) , m_FontMetrics(QFont()) { - m_Utf8Codec = QTextCodec::codecForName("utf-8"); - m_LocalCodec = QTextCodec::codecForName("Windows-1252"); - - if (m_LocalCodec == nullptr) { - qCritical("required 8-bit string-encoding not supported."); - m_LocalCodec = m_Utf8Codec; - } - } PluginList::~PluginList() @@ -117,27 +110,25 @@ QString PluginList::getColumnToolTip(int column) void PluginList::refresh(const QString &profileName , const DirectoryEntry &baseDirectory - , const QString &pluginsFile - , const QString &loadOrderFile , const QString &lockedOrderFile) { ChangeBracket layoutChange(this); - m_ESPsByName.clear(); - m_ESPsByPriority.clear(); - m_ESPs.clear(); - QStringList primaryPlugins = m_GamePlugin->primaryPlugins(); m_CurrentProfile = profileName; std::vector files = baseDirectory.getFiles(); - for (auto iter = files.begin(); iter != files.end(); ++iter) { - FileEntry::Ptr current = *iter; + for (FileEntry::Ptr current : files) { if (current.get() == nullptr) { continue; } QString filename = ToQString(current->getName()); + + if (m_ESPsByName.find(filename.toLower()) != m_ESPsByName.end()) { + continue; + } + QString extension = filename.right(3).toLower(); if ((extension == "esp") || (extension == "esm")) { @@ -165,56 +156,24 @@ void PluginList::refresh(const QString &profileName } } - if (readLoadOrder(loadOrderFile)) { - int maxPriority = 0; - // assign known load orders - for (std::vector::iterator espIter = m_ESPs.begin(); espIter != m_ESPs.end(); ++espIter) { - std::map::const_iterator priorityIter = m_ESPLoadOrder.find(espIter->m_Name.toLower()); - if (priorityIter != m_ESPLoadOrder.end()) { - if (priorityIter->second > maxPriority) { - maxPriority = priorityIter->second; - } - espIter->m_Priority = priorityIter->second; - } else { - espIter->m_Priority = -1; - } - } - - ++maxPriority; - - // assign maximum priorities for plugins with unknown priority - for (std::vector::iterator espIter = m_ESPs.begin(); espIter != m_ESPs.end(); ++espIter) { - if (espIter->m_Priority == -1) { - espIter->m_Priority = maxPriority++; - } - } - } else { - // no load order stored, determine by date - std::sort(m_ESPs.begin(), m_ESPs.end(), ByDate); - - for (size_t i = 0; i < m_ESPs.size(); ++i) { - m_ESPs[i].m_Priority = i; - } - } + // functions in GamePlugins will use the IPluginList interface of this, so + // indices need to work. priority will be off however + updateIndices(); - std::sort(m_ESPs.begin(), m_ESPs.end(), ByPriority); // first, sort by priority - // remove gaps from the priorities so we can use them as array indices without overflow - for (int i = 0; i < static_cast(m_ESPs.size()); ++i) { - m_ESPs[i].m_Priority = i; - } + GamePlugins *gamePlugins = m_GamePlugin->feature(); + gamePlugins->readPluginLists(this); - std::sort(m_ESPs.begin(), m_ESPs.end(), ByName); // sort by name so alphabetical sorting works + testMasters(); updateIndices(); - readEnabledFrom(pluginsFile); - readLockedOrderFrom(lockedOrderFile); layoutChange.finish(); refreshLoadOrder(); - emit dataChanged(this->index(0, 0), this->index(m_ESPs.size(), columnCount())); + emit dataChanged(this->index(0, 0), + this->index(static_cast(m_ESPs.size()), columnCount())); m_Refreshed(); } @@ -301,89 +260,6 @@ bool PluginList::isEnabled(int index) return m_ESPs.at(index).m_Enabled; } -bool PluginList::readLoadOrder(const QString &fileName) -{ - std::set availableESPs; - for (std::vector::const_iterator iter = m_ESPs.begin(); iter != m_ESPs.end(); ++iter) { - availableESPs.insert(iter->m_Name.toLower()); - } - - m_ESPLoadOrder.clear(); - - int priority = 0; - - QStringList primaryPlugins = m_GamePlugin->primaryPlugins(); - for (const QString &plugin : primaryPlugins) { - if (availableESPs.find(plugin) != availableESPs.end()) { - m_ESPLoadOrder[plugin] = priority++; - } - } - - QFile file(fileName); - if (!file.open(QIODevice::ReadOnly)) { - return false; - } - if (file.size() == 0) { - // MO stores at least a header in the file. if it's completely empty the file is broken - return false; - } - while (!file.atEnd()) { - QByteArray line = file.readLine().trimmed(); - QString modName; - if ((line.size() > 0) && (line.at(0) != '#')) { - modName = QString::fromUtf8(line.constData()).toLower(); - } - - if ((modName.size() > 0) && - (m_ESPLoadOrder.find(modName) == m_ESPLoadOrder.end()) && - (availableESPs.find(modName) != availableESPs.end())) { - m_ESPLoadOrder[modName] = priority++; - } - } - - file.close(); - return true; -} - - -void PluginList::readEnabledFrom(const QString &fileName) -{ - for (std::vector::iterator iter = m_ESPs.begin(); iter != m_ESPs.end(); ++iter) { - if (!iter->m_ForceEnabled) { - iter->m_Enabled = false; - } - iter->m_LoadOrder = -1; - } - - QFile file(fileName); - if (!file.exists()) { - throw std::runtime_error(QObject::tr("failed to find \"%1\"").arg(fileName).toUtf8().constData()); - } - - file.open(QIODevice::ReadOnly); - while (!file.atEnd()) { - QByteArray line = file.readLine(); - QString modName; - if ((line.size() > 0) && (line.at(0) != '#')) { - modName = m_LocalCodec->toUnicode(line.trimmed().constData()); - } - if (modName.size() > 0) { - std::map::iterator iter = m_ESPsByName.find(modName.toLower()); - if (iter != m_ESPsByName.end()) { - m_ESPs[iter->second].m_Enabled = true; - } else { - qWarning("plugin %s not found", modName.toUtf8().constData()); - emit writePluginsList(); - } - } - } - - file.close(); - - testMasters(); -} - - void PluginList::readLockedOrderFrom(const QString &fileName) { m_LockedOrder.clear(); @@ -410,53 +286,6 @@ void PluginList::readLockedOrderFrom(const QString &fileName) file.close(); } - - -void PluginList::writePlugins(const QString &fileName, bool writeUnchecked) const -{ - SafeWriteFile file(fileName); - - QTextCodec *textCodec = writeUnchecked ? m_Utf8Codec : m_LocalCodec; - - file->resize(0); - - file->write(textCodec->fromUnicode("# This file was automatically generated by Mod Organizer.\r\n")); - - QStringList saveList; - - bool invalidFileNames = false; - int writtenCount = 0; - for (size_t i = 0; i < m_ESPs.size(); ++i) { - int priority = m_ESPsByPriority[i]; - if (m_ESPs[priority].m_Enabled || writeUnchecked) { - //file.write(m_ESPs[priority].m_Name.toUtf8()); - if (!textCodec->canEncode(m_ESPs[priority].m_Name)) { - invalidFileNames = true; - qCritical("invalid plugin name %s", m_ESPs[priority].m_Name.toUtf8().constData()); - } else { - saveList << m_ESPs[priority].m_Name; - file->write(textCodec->fromUnicode(m_ESPs[priority].m_Name)); - } - file->write("\r\n"); - ++writtenCount; - } - } - - if (invalidFileNames) { - reportError(tr("Some of your plugins have invalid names! These plugins can not be loaded by the game. " - "Please see mo_interface.log for a list of affected plugins and rename them.")); - } - - if (writtenCount == 0) { - qWarning("plugin list would be empty, this is almost certainly wrong. Not saving."); - } else { - if (file.commitIfDifferent(m_LastSaveHash[fileName])) { - qDebug("%s saved", QDir::toNativeSeparators(fileName).toUtf8().constData()); - } - } -} - - void PluginList::writeLockedOrder(const QString &fileName) const { SafeWriteFile file(fileName); @@ -471,14 +300,13 @@ void PluginList::writeLockedOrder(const QString &fileName) const } -void PluginList::saveTo(const QString &pluginFileName - , const QString &loadOrderFileName - , const QString &lockedOrderFileName +void PluginList::saveTo(const QString &lockedOrderFileName , const QString& deleterFileName , bool hideUnchecked) const { - writePlugins(pluginFileName, false); - writePlugins(loadOrderFileName, true); + GamePlugins *gamePlugins = m_GamePlugin->feature(); + gamePlugins->writePluginLists(this); + writeLockedOrder(lockedOrderFileName); if (hideUnchecked) { @@ -552,7 +380,7 @@ bool PluginList::saveLoadOrder(DirectoryEntry &directoryStructure) int PluginList::enabledCount() const { int enabled = 0; - foreach (auto info, m_ESPs) { + for (const auto &info : m_ESPs) { if (info.m_Enabled) { ++enabled; } @@ -606,7 +434,7 @@ void PluginList::refreshLoadOrder() bool savePluginsList = false; // this is guaranteed to iterate from lowest key (load order) to highest for (auto iter = lockedLoadOrder.begin(); iter != lockedLoadOrder.end(); ++iter) { - auto nameIter = m_ESPsByName.find(iter->second); + auto nameIter = m_ESPsByName.find(iter->second.toLower()); if (nameIter != m_ESPsByName.end()) { // locked esp exists @@ -641,6 +469,17 @@ void PluginList::disconnectSlots() { m_PluginStateChanged.disconnect_all_slots(); } +QStringList PluginList::pluginNames() const +{ + QStringList result; + + for (const ESPInfo &info : m_ESPs) { + result.append(info.m_Name); + } + + return result; +} + IPluginList::PluginStates PluginList::state(const QString &name) const { auto iter = m_ESPsByName.find(name.toLower()); @@ -651,6 +490,36 @@ IPluginList::PluginStates PluginList::state(const QString &name) const } } +void PluginList::setState(const QString &name, PluginStates state) +{ + auto iter = m_ESPsByName.find(name.toLower()); + if (iter != m_ESPsByName.end()) { + m_ESPs[iter->second].m_Enabled = state == IPluginList::STATE_ACTIVE; + } +} + +void PluginList::setLoadOrder(const QStringList &pluginList) +{ + for (ESPInfo &info : m_ESPs) { + info.m_Priority = -1; + } + int maxPriority = 0; + for (const QString &plugin : pluginList) { + auto iter = m_ESPsByName.find(plugin.toLower()); + if (iter !=m_ESPsByName.end()) { + m_ESPs[iter->second].m_Priority = maxPriority++; + } + } + + // use old priorities + for (ESPInfo &info : m_ESPs) { + if (info.m_Priority == -1) { + info.m_Priority = maxPriority++; + } + } + updateIndices(); +} + int PluginList::priority(const QString &name) const { auto iter = m_ESPsByName.find(name.toLower()); @@ -688,7 +557,7 @@ QStringList PluginList::masters(const QString &name) const return QStringList(); } else { QStringList result; - foreach (const QString &master, m_ESPs[iter->second].m_Masters) { + for (const QString &master : m_ESPs[iter->second].m_Masters) { result.append(master); } return result; @@ -730,10 +599,16 @@ void PluginList::updateIndices() m_ESPsByName.clear(); m_ESPsByPriority.clear(); m_ESPsByPriority.resize(m_ESPs.size()); - for (unsigned int i = 0; i < m_ESPs.size(); ++i) { + if (m_ESPs[i].m_Priority < 0) { + continue; + } + if (m_ESPs[i].m_Priority >= static_cast(m_ESPs.size())) { + qCritical("invalid priority %d", m_ESPs[i].m_Priority); + continue; + } m_ESPsByName[m_ESPs[i].m_Name.toLower()] = i; - m_ESPsByPriority[m_ESPs[i].m_Priority] = i; + m_ESPsByPriority.at(static_cast(m_ESPs[i].m_Priority)) = i; } } @@ -741,7 +616,7 @@ void PluginList::updateIndices() int PluginList::rowCount(const QModelIndex &parent) const { if (!parent.isValid()) { - return m_ESPs.size(); + return static_cast(m_ESPs.size()); } else { return 0; } @@ -926,7 +801,9 @@ bool PluginList::setData(const QModelIndex &modIndex, const QVariant &value, int try { m_PluginStateChanged(modName, newState); testMasters(); - emit dataChanged(this->index(0, 0), this->index(m_ESPs.size(), columnCount())); + emit dataChanged( + this->index(0, 0), + this->index(static_cast(m_ESPs.size()), columnCount())); } catch (const std::exception &e) { qCritical("failed to invoke state changed notification: %s", e.what()); } catch (...) { @@ -1002,8 +879,10 @@ void PluginList::setPluginPriority(int row, int &newPriority) } // enforce valid range - if (newPriorityTemp < 0) newPriorityTemp = 0; - else if (newPriorityTemp >= static_cast(m_ESPsByPriority.size())) newPriorityTemp = m_ESPsByPriority.size() - 1; + if (newPriorityTemp < 0) + newPriorityTemp = 0; + else if (newPriorityTemp >= static_cast(m_ESPsByPriority.size())) + newPriorityTemp = static_cast(m_ESPsByPriority.size()) - 1; try { int oldPriority = m_ESPs.at(row).m_Priority; @@ -1089,7 +968,7 @@ bool PluginList::dropMimeData(const QMimeData *mimeData, Qt::DropAction action, if ((row < 0) || (row >= static_cast(m_ESPs.size()))) { - newPriority = m_ESPs.size(); + newPriority = static_cast(m_ESPs.size()); } else { newPriority = m_ESPs[row].m_Priority; } @@ -1210,7 +1089,7 @@ PluginList::ESPInfo::ESPInfo(const QString &name, bool enabled, } } -void PluginList::managedGameChanged(IPluginGame const *gamePlugin) +void PluginList::managedGameChanged(const IPluginGame *gamePlugin) { m_GamePlugin = gamePlugin; } -- cgit v1.3.1