summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/modlist.cpp44
-rw-r--r--src/organizercore.cpp6
-rw-r--r--src/pluginlist.cpp32
-rw-r--r--src/profile.cpp71
-rw-r--r--src/profile.h6
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 &section, const QString &name,
void Profile::removeSetting(const QString &section, 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 &section, 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;