diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/modlist.cpp | 44 | ||||
| -rw-r--r-- | src/organizercore.cpp | 6 | ||||
| -rw-r--r-- | src/pluginlist.cpp | 32 | ||||
| -rw-r--r-- | src/profile.cpp | 71 | ||||
| -rw-r--r-- | src/profile.h | 6 |
5 files changed, 100 insertions, 59 deletions
diff --git a/src/modlist.cpp b/src/modlist.cpp index 6caafeb2..7b57eeda 100644 --- a/src/modlist.cpp +++ b/src/modlist.cpp @@ -654,26 +654,48 @@ void ModList::changeModPriority(std::vector<int> sourceIndices, int newPriority) emit layoutAboutToBeChanged();
Profile *profile = m_Profile;
- // sort rows to insert by their old priority (ascending) and insert them move them in that order
+
+ // sort the moving mods by ascending priorities
std::sort(sourceIndices.begin(), sourceIndices.end(),
- [profile](const int &LHS, const int &RHS) {
- return profile->getModPriority(LHS) < profile->getModPriority(RHS);
- });
+ [profile](const int &LHS, const int &RHS) {
+ return profile->getModPriority(LHS) > profile->getModPriority(RHS);
+ });
- // odd stuff: if any of the dragged sources has priority lower than the destination then the
- // target idx is that of the row BELOW the dropped location, otherwise it's the one above. why?
+ // move mods that are decreasing in priority
for (std::vector<int>::const_iterator iter = sourceIndices.begin();
iter != sourceIndices.end(); ++iter) {
- if (profile->getModPriority(*iter) < newPriority) {
+ int oldPriority = profile->getModPriority(*iter);
+ if (oldPriority > newPriority) {
+ profile->setModPriority(*iter, newPriority);
+ m_ModMoved(ModInfo::getByIndex(*iter)->name(), oldPriority, newPriority);
+ }
+ }
+
+ // sort the moving mods by descending priorities
+ std::sort(sourceIndices.begin(), sourceIndices.end(),
+ [profile](const int &LHS, const int &RHS) {
+ return profile->getModPriority(LHS) < profile->getModPriority(RHS);
+ });
+
+ // if at least one mod is increasing in priority, the target index is
+ // that of the row BELOW the dropped location, otherwise it's the one above
+ for (std::vector<int>::const_iterator iter = sourceIndices.begin();
+ iter != sourceIndices.end(); ++iter) {
+ int oldPriority = profile->getModPriority(*iter);
+ if (oldPriority < newPriority) {
--newPriority;
break;
}
}
+
+ // move mods that are increasing in priority
for (std::vector<int>::const_iterator iter = sourceIndices.begin();
- iter != sourceIndices.end(); ++iter) {
- int oldPriority = m_Profile->getModPriority(*iter);
- m_Profile->setModPriority(*iter, newPriority);
- m_ModMoved(ModInfo::getByIndex(*iter)->name(), oldPriority, newPriority);
+ iter != sourceIndices.end(); ++iter) {
+ int oldPriority = profile->getModPriority(*iter);
+ if (oldPriority < newPriority) {
+ profile->setModPriority(*iter, newPriority);
+ m_ModMoved(ModInfo::getByIndex(*iter)->name(), oldPriority, newPriority);
+ }
}
emit layoutChanged();
diff --git a/src/organizercore.cpp b/src/organizercore.cpp index 5c85e323..1fafd4c1 100644 --- a/src/organizercore.cpp +++ b/src/organizercore.cpp @@ -1183,7 +1183,9 @@ ModList *OrganizerCore::modList() QStringList OrganizerCore::modsSortedByProfilePriority() const
{
QStringList res;
- for (unsigned int i = 0; i < currentProfile()->numRegularMods(); ++i) {
+ for (int i = currentProfile()->getPriorityMinimum();
+ i < currentProfile()->getPriorityMinimum() + currentProfile()->numRegularMods();
+ ++i) {
int modIndex = currentProfile()->modIndexByPriority(i);
res.push_back(ModInfo::getByIndex(modIndex)->name());
}
@@ -2304,4 +2306,4 @@ std::vector<Mapping> OrganizerCore::fileMapping( result.insert(result.end(), subRes.begin(), subRes.end());
}
return result;
-}
\ No newline at end of file +}
diff --git a/src/pluginlist.cpp b/src/pluginlist.cpp index 4097ba98..8f714afd 100644 --- a/src/pluginlist.cpp +++ b/src/pluginlist.cpp @@ -1183,17 +1183,35 @@ void PluginList::setPluginPriority(int row, int &newPriority) void PluginList::changePluginPriority(std::vector<int> rows, int newPriority)
{
ChangeBracket<PluginList> layoutChange(this);
- // sort rows to insert by their old priority (ascending) and insert them move them in that order
const std::vector<ESPInfo> &esp = m_ESPs;
+
+ int minPriority = INT_MAX;
+ int maxPriority = INT_MIN;
+
+ // don't try to move plugins before force-enabled plugins
+ for (std::vector<ESPInfo>::const_iterator iter = m_ESPs.begin();
+ iter != m_ESPs.end(); ++iter) {
+ if (iter->m_ForceEnabled) {
+ newPriority = std::max(newPriority, iter->m_Priority+1);
+ }
+ maxPriority = std::max(maxPriority, iter->m_Priority+1);
+ minPriority = std::min(minPriority, iter->m_Priority);
+ }
+
+ // limit the new priority to existing priorities
+ newPriority = std::min(newPriority, maxPriority);
+ newPriority = std::max(newPriority, minPriority);
+
+ // sort the moving plugins by ascending priorities
std::sort(rows.begin(), rows.end(),
- [&esp](const int &LHS, const int &RHS) {
- return esp[LHS].m_Priority < esp[RHS].m_Priority;
- });
+ [&esp](const int &LHS, const int &RHS) {
+ return esp[LHS].m_Priority < esp[RHS].m_Priority;
+ });
- // odd stuff: if any of the dragged sources has priority lower than the destination then the
- // target idx is that of the row BELOW the dropped location, otherwise it's the one above. why?
+ // if at least on plugin is increasing in priority, the target index is
+ // that of the row BELOW the dropped location, otherwise it's the one above
for (std::vector<int>::const_iterator iter = rows.begin();
- iter != rows.end(); ++iter) {
+ iter != rows.end(); ++iter) {
if (m_ESPs[*iter].m_Priority < newPriority) {
--newPriority;
break;
diff --git a/src/profile.cpp b/src/profile.cpp index 7f10bd02..00818d0b 100644 --- a/src/profile.cpp +++ b/src/profile.cpp @@ -184,9 +184,10 @@ void Profile::doWriteModlist() return; } - for (int i = static_cast<int>(m_ModStatus.size()) - 1; i >= 0; --i) { + for (std::map<int, unsigned int>::const_reverse_iterator iter = m_ModIndexByPriority.crbegin(); iter != m_ModIndexByPriority.crend(); iter++ ) { + //qDebug(QString("write mod %1 to priority %2").arg(iter->first).arg(iter->second).toLocal8Bit()); // the priority order was inverted on load so it has to be inverted again - unsigned int index = m_ModIndexByPriority[i]; + unsigned int index = iter->second; if (index != UINT_MAX) { ModInfo::Ptr modInfo = ModInfo::getByIndex(index); std::vector<ModInfo::EFlag> flags = modInfo->getFlags(); @@ -223,9 +224,9 @@ void Profile::createTweakedIniFile() return; } - for (unsigned int i = 0; i < m_ModStatus.size(); ++i) { + for (int i = getPriorityMinimum(); i < getPriorityMinimum() + (int)numRegularMods(); ++i) { unsigned int idx = modIndexByPriority(i); - if ((idx != UINT_MAX) && m_ModStatus[idx].m_Enabled) { + if (m_ModStatus[idx].m_Enabled) { ModInfo::Ptr modInfo = ModInfo::getByIndex(idx); mergeTweaks(modInfo, tweakedIni); } @@ -454,18 +455,14 @@ void Profile::updateIndices() { m_NumRegularMods = 0; m_ModIndexByPriority.clear(); - m_ModIndexByPriority.resize(m_ModStatus.size(), UINT_MAX); for (unsigned int i = 0; i < m_ModStatus.size(); ++i) { int priority = m_ModStatus[i].m_Priority; - if (priority < 0) { + if (priority == INT_MIN) { // don't assign this to mapping at all, it's probably the overwrite mod continue; - } else if (priority >= static_cast<int>(m_ModIndexByPriority.size())) { - qCritical("invalid priority %d for mod", priority); - continue; } else { ++m_NumRegularMods; - m_ModIndexByPriority.at(priority) = i; + m_ModIndexByPriority[priority] = i; } } } @@ -474,11 +471,10 @@ void Profile::updateIndices() std::vector<std::tuple<QString, QString, int> > Profile::getActiveMods() { std::vector<std::tuple<QString, QString, int> > result; - for (std::vector<unsigned int>::const_iterator iter = m_ModIndexByPriority.begin(); - iter != m_ModIndexByPriority.end(); ++iter) { - if ((*iter != UINT_MAX) && m_ModStatus[*iter].m_Enabled) { - ModInfo::Ptr modInfo = ModInfo::getByIndex(*iter); - result.push_back(std::make_tuple(modInfo->internalName(), modInfo->absolutePath(), m_ModStatus[*iter].m_Priority)); + for (std::map<int, unsigned int>::const_iterator iter = m_ModIndexByPriority.begin(); iter != m_ModIndexByPriority.end(); iter++ ) { + if ((iter->second != UINT_MAX) && m_ModStatus[iter->second].m_Enabled) { + ModInfo::Ptr modInfo = ModInfo::getByIndex(iter->second); + result.push_back(std::make_tuple(modInfo->internalName(), modInfo->absolutePath(), m_ModStatus[iter->second].m_Priority)); } } @@ -496,13 +492,13 @@ std::vector<std::tuple<QString, QString, int> > Profile::getActiveMods() } -unsigned int Profile::modIndexByPriority(unsigned int priority) const +unsigned int Profile::modIndexByPriority(int priority) const { - if (priority >= m_ModStatus.size()) { + try { + return m_ModIndexByPriority.at(priority); + } catch (std::out_of_range) { throw MyException(tr("invalid priority %1").arg(priority)); } - - return m_ModIndexByPriority[priority]; } @@ -552,30 +548,26 @@ void Profile::setModPriority(unsigned int index, int &newPriority) return; } - int newPriorityTemp = - (std::max)(0, (std::min<int>)(static_cast<int>(m_ModStatus.size()) - 1, - newPriority)); + int oldPriority = m_ModStatus.at(index).m_Priority; + int lastPriority = INT_MIN; - // don't try to place below overwrite - while ((m_ModIndexByPriority.at(newPriorityTemp) >= m_ModStatus.size()) || - m_ModStatus.at(m_ModIndexByPriority.at(newPriorityTemp)).m_Overwrite) { - --newPriorityTemp; + if (newPriority == oldPriority) { + // nothing to do + return; } - int oldPriority = m_ModStatus.at(index).m_Priority; - if (newPriorityTemp > oldPriority) { - // priority is higher than the old, so the gap we left is in lower priorities - for (int i = oldPriority + 1; i <= newPriorityTemp; ++i) { - --m_ModStatus.at(m_ModIndexByPriority.at(i)).m_Priority; + for (std::map<int, unsigned int>::iterator iter = m_ModIndexByPriority.begin(); iter != m_ModIndexByPriority.end(); iter++) { + if (newPriority < oldPriority && iter->first >= newPriority && iter->first < oldPriority) { + m_ModStatus.at(iter->second).m_Priority += 1; } - } else { - for (int i = newPriorityTemp; i < oldPriority; ++i) { - ++m_ModStatus.at(m_ModIndexByPriority.at(i)).m_Priority; + else if (newPriority > oldPriority && iter->first <= newPriority && iter->first > oldPriority) { + m_ModStatus.at(iter->second).m_Priority -= 1; } - ++newPriority; + lastPriority = std::max(lastPriority, iter->first); } - m_ModStatus.at(index).m_Priority = newPriorityTemp; + newPriority = std::min(newPriority, lastPriority); + m_ModStatus.at(index).m_Priority = std::min(newPriority, lastPriority); updateIndices(); m_ModListWriter.write(); @@ -839,4 +831,9 @@ void Profile::storeSetting(const QString §ion, const QString &name, void Profile::removeSetting(const QString §ion, const QString &name) { m_Settings->remove(section + "/" + name); -}
\ No newline at end of file +} + +int Profile::getPriorityMinimum() const +{ + return m_ModIndexByPriority.begin()->first; +} diff --git a/src/profile.h b/src/profile.h index 1fcad046..9ddd5b89 100644 --- a/src/profile.h +++ b/src/profile.h @@ -247,7 +247,7 @@ public: * @return the index of the mod * @throw std::exception an exception is thrown if there is no mod with the specified priority **/ - unsigned int modIndexByPriority(unsigned int priority) const; + unsigned int modIndexByPriority(int priority) const; /** * @brief enable or disable a mod @@ -294,6 +294,8 @@ public: const QVariant &value); void removeSetting(const QString §ion, const QString &name); + int getPriorityMinimum() const; + signals: /** @@ -347,7 +349,7 @@ private: mutable QByteArray m_LastModlistHash; std::vector<ModStatus> m_ModStatus; - std::vector<unsigned int> m_ModIndexByPriority; + std::map<int, unsigned int> m_ModIndexByPriority; unsigned int m_NumRegularMods; MOBase::DelayedFileWriter m_ModListWriter; |
