fix(ModFolderPage): preserve profile state synchronization during cleanup

Signed-off-by: Vivek Kushwaha <notvivekkushwaha@gmail.com>
This commit is contained in:
Vivek Kushwaha 2026-06-23 17:53:36 +05:30
parent 352b45bf5e
commit 8e85ecfd43
4 changed files with 12 additions and 348 deletions

View file

@ -40,20 +40,10 @@
#include "minecraft/MinecraftInstance.h"
#include "minecraft/mod/ModFolderModel.h"
#include <QThread>
#include <QAtomicInt>
#include <QDebug>
extern QAtomicInt g_logSequence;
extern QString getActiveProfileForModel(void* modelPtr);
ScanModFolders::ScanModFolders(LaunchTask* parent) : LaunchStep(parent) {}
ScanModFolders::~ScanModFolders()
{
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence
<< "ScanModFolders::~ScanModFolders()"
<< "thread:" << QThread::currentThreadId();
}
void ScanModFolders::executeTask()
@ -64,13 +54,6 @@ void ScanModFolders::executeTask()
auto cores = m_inst->coreModList();
auto nils = m_inst->nilModList();
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence
<< "ScanModFolders::executeTask() START"
<< "thread:" << QThread::currentThreadId()
<< "loaderModel:" << loaders << "profile:" << getActiveProfileForModel(loaders)
<< "coreModel:" << cores << "profile:" << getActiveProfileForModel(cores)
<< "nilModel:" << nils << "profile:" << getActiveProfileForModel(nils);
m_modsConnection = connect(loaders, &ModFolderModel::updateFinished, this, &ScanModFolders::modsDone);
if (!loaders->update()) {
m_modsDone = true;
@ -109,17 +92,6 @@ void ScanModFolders::nilModsDone()
void ScanModFolders::checkDone()
{
if (m_modsDone && m_coreModsDone && m_nilModsDone) {
auto m_inst = m_parent->instance();
auto loaders = m_inst->loaderModList();
auto cores = m_inst->coreModList();
auto nils = m_inst->nilModList();
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence
<< "ScanModFolders::checkDone() END"
<< "thread:" << QThread::currentThreadId()
<< "loaderModel:" << loaders << "profile:" << getActiveProfileForModel(loaders)
<< "coreModel:" << cores << "profile:" << getActiveProfileForModel(cores)
<< "nilModel:" << nils << "profile:" << getActiveProfileForModel(nils);
// Sever the connections to the persistent ModFolderModel singletons.
// Without this, updateFinished() would re-invoke these slots the next

View file

@ -1,12 +1,6 @@
#include "ResourceFolderModel.h"
#include <QMessageBox>
#include <QThread>
#include <QAtomicInt>
extern QAtomicInt g_logSequence;
extern QString getActiveProfileForModel(void* modelPtr);
#include <QCoreApplication>
#include <QDebug>
#include <QFileInfo>
@ -308,29 +302,9 @@ bool ResourceFolderModel::setResourceEnabled(const QModelIndexList& indexes, Ena
auto& resource = m_resources[row];
QString originalName = resource->getOriginalFileName();
QString oldPath = resource->fileinfo().absoluteFilePath();
bool wasEnabled = resource->enabled();
qDebug() << "[INSTRUMENTATION-MUTATION]" << ++g_logSequence
<< "setResourceEnabled() START"
<< "resource:" << originalName
<< "wasEnabled:" << wasEnabled
<< "oldPath:" << oldPath
<< "action:" << (action == EnableAction::ENABLE ? "ENABLE" : (action == EnableAction::DISABLE ? "DISABLE" : "TOGGLE"));
// Preserve the row, but change its ID
auto oldId = resource->internalId();
bool ok = resource->enable(action);
qDebug() << "[INSTRUMENTATION-MUTATION]" << ++g_logSequence
<< "setResourceEnabled() END"
<< "resource:" << originalName
<< "nowEnabled:" << resource->enabled()
<< "newPath:" << resource->fileinfo().absoluteFilePath()
<< "succeeded:" << ok;
if (!ok) {
if (!resource->enable(action)) {
succeeded = false;
continue;
}
@ -340,12 +314,6 @@ bool ResourceFolderModel::setResourceEnabled(const QModelIndexList& indexes, Ena
m_resourcesIndex.remove(oldId);
m_resourcesIndex[newId] = row;
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence
<< "EMIT dataChanged() (setResourceEnabled)"
<< "row:" << row
<< "thread:" << QThread::currentThreadId()
<< "model:" << this
<< "profile:" << getActiveProfileForModel(this);
emit dataChanged(index(row, 0), index(row, columnCount(QModelIndex()) - 1));
}
@ -380,11 +348,6 @@ bool ResourceFolderModel::update()
m_scheduledUpdate = false;
update();
} else {
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence
<< "EMIT updateFinished()"
<< "thread:" << QThread::currentThreadId()
<< "model:" << this
<< "profile:" << getActiveProfileForModel(this);
emit updateFinished();
}
},
@ -469,12 +432,6 @@ void ResourceFolderModel::onParseSucceeded(int ticket, const QString& resourceId
}
int row = m_resourcesIndex[resourceId];
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence
<< "EMIT dataChanged() (onParseSucceeded)"
<< "row:" << row
<< "thread:" << QThread::currentThreadId()
<< "model:" << this
<< "profile:" << getActiveProfileForModel(this);
emit dataChanged(index(row), index(row, columnCount(QModelIndex()) - 1));
}
@ -899,21 +856,6 @@ void ResourceFolderModel::onParseFailed(int ticket, const QString& resourceId)
void ResourceFolderModel::applyUpdates(QSet<QString>& currentSet, QSet<QString>& newSet, QMap<QString, Resource::Ptr>& newResources)
{
{
QSet<QString> enabledBefore;
for (const auto& res : m_resources) {
if (res->enabled()) {
enabledBefore.insert(res->getOriginalFileName());
}
}
qDebug() << "[INSTRUMENTATION-APPLYUPDATES] START"
<< "seq:" << ++g_logSequence
<< "profile:" << getActiveProfileForModel(this)
<< "enabledBefore:" << enabledBefore
<< "currentSet:" << currentSet
<< "newSet:" << newSet;
}
// see if the kept resources changed in some way
{
QSet<QString> keptSet = currentSet;
@ -933,12 +875,6 @@ void ResourceFolderModel::applyUpdates(QSet<QString>& currentSet, QSet<QString>&
currentResource->updateIssues(m_instance);
if (hadIssues != currentResource->hasIssues()) {
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence
<< "EMIT dataChanged() (applyUpdates unchanged file)"
<< "row:" << row
<< "thread:" << QThread::currentThreadId()
<< "model:" << this
<< "profile:" << getActiveProfileForModel(this);
emit dataChanged(index(row, 0), index(row, columnCount({}) - 1));
}
continue;
@ -958,12 +894,6 @@ void ResourceFolderModel::applyUpdates(QSet<QString>& currentSet, QSet<QString>&
newResource->updateIssues(m_instance);
resolveResource(m_resources.at(row));
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence
<< "EMIT dataChanged() (applyUpdates changed file)"
<< "row:" << row
<< "thread:" << QThread::currentThreadId()
<< "model:" << this
<< "profile:" << getActiveProfileForModel(this);
emit dataChanged(index(row, 0), index(row, columnCount(QModelIndex()) - 1));
}
}
@ -1029,42 +959,6 @@ void ResourceFolderModel::applyUpdates(QSet<QString>& currentSet, QSet<QString>&
idx++;
}
}
{
QSet<QString> enabledAfter;
for (const auto& res : m_resources) {
if (res->enabled()) {
enabledAfter.insert(res->getOriginalFileName());
}
}
QSet<QString> keptSet = currentSet;
keptSet.intersect(newSet);
QSet<QString> removedSet = currentSet;
removedSet.subtract(newSet);
QSet<QString> addedSet = newSet;
addedSet.subtract(currentSet);
qDebug() << "[INSTRUMENTATION-APPLYUPDATES] END"
<< "seq:" << ++g_logSequence
<< "profile:" << getActiveProfileForModel(this)
<< "enabledAfter:" << enabledAfter
<< "added:" << addedSet
<< "removed:" << removedSet;
for (const auto& kept : keptSet) {
auto rowIt = m_resourcesIndex.constFind(kept);
if (rowIt != m_resourcesIndex.constEnd()) {
auto row = rowIt.value();
auto& newResource = newResources[kept];
const auto& currentResource = m_resources.at(row);
if (newResource->enabled() != currentResource->enabled()) {
qDebug() << " -> kept resource changed enabled state:" << kept
<< "before:" << currentResource->enabled()
<< "after:" << newResource->enabled();
}
}
}
}
}
Resource::Ptr ResourceFolderModel::find(QString id)
{

View file

@ -73,66 +73,9 @@
#include "tasks/Task.h"
#include "ui/dialogs/ProgressDialog.h"
#include <QMutex>
#include <QMap>
#include <QThread>
#include <QAtomicInt>
QMutex g_activeProfilesMutex;
QMap<void*, QString> g_activeProfiles;
QAtomicInt g_logSequence(0);
QString getActiveProfileForModel(void* modelPtr) {
QMutexLocker locker(&g_activeProfilesMutex);
return g_activeProfiles.value(modelPtr, QStringLiteral("Unknown/None"));
}
void setActiveProfileForModel(void* modelPtr, const QString& profile) {
QMutexLocker locker(&g_activeProfilesMutex);
g_activeProfiles[modelPtr] = profile;
}
void compareModelToProfileState(const QString& stage, ModFolderModel* model, const QSet<QString>& expectedMods, int seq) {
QSet<QString> actualMods;
for (int i = 0; i < model->rowCount(); ++i) {
const Resource& res = model->at(i);
if (res.enabled()) {
actualMods.insert(res.getOriginalFileName());
}
}
bool match = (expectedMods == actualMods);
qDebug() << "[INSTRUMENTATION-DIVERGE]" << seq << stage
<< "expectedCount:" << expectedMods.size()
<< "actualCount:" << actualMods.size()
<< "match:" << match;
if (!match) {
QSet<QString> missing = expectedMods;
missing.subtract(actualMods);
QSet<QString> unexpected = actualMods;
unexpected.subtract(expectedMods);
qDebug() << " -> Expected Set:" << expectedMods;
qDebug() << " -> Actual Set:" << actualMods;
qDebug() << " -> Missing mods:" << missing;
qDebug() << " -> Unexpected enabled mods:" << unexpected;
}
}
ModFolderPage::~ModFolderPage()
{
m_destructorStarted = true;
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence << "ModFolderPage::~ModFolderPage() entered"
<< "thread:" << QThread::currentThreadId()
<< "model:" << m_model
<< "currentProfile:" << m_currentProfile
<< "destructorStarted:" << m_destructorStarted;
{
QMutexLocker locker(&g_activeProfilesMutex);
g_activeProfiles.remove(m_model);
}
if (m_filterWindow) {
m_filterWindow->removeEventFilter(this);
@ -142,7 +85,6 @@ ModFolderPage::~ModFolderPage()
}
}
ModFolderPage::ModFolderPage(BaseInstance* inst, ModFolderModel* model, QWidget* parent)
: ExternalResourcesPage(inst, model, parent), m_model(model)
{
@ -150,7 +92,7 @@ ModFolderPage::ModFolderPage(BaseInstance* inst, ModFolderModel* model, QWidget*
m_profileTabBar->setExpanding(false);
m_profileTabBar->setDrawBase(false); // no underline bar — matches Settings tab style
m_profileTabBar->setDocumentMode(false);
m_profileTabBar->setUsesScrollButtons(true);
m_profileTabBar->setUsesScrollButtons(m_profileTabBar->count() > 1);
m_profileTabBar->setElideMode(Qt::ElideRight);
m_profileTabBar->setContextMenuPolicy(Qt::CustomContextMenu);
// Palette-based stylesheet: selected tab uses palette(base) to match the
@ -258,23 +200,14 @@ ModFolderPage::ModFolderPage(BaseInstance* inst, ModFolderModel* model, QWidget*
m_profileTabBar->blockSignals(true);
for (const QString& name : profileList) {
m_profileTabBar->addTab(name);
QString key = profileKey(name);
m_instance->settings()->getOrRegisterSetting(key, QStringList());
QStringList saved = m_instance->settings()->get(key).toStringList();
m_profileStates[name] = QSet<QString>(saved.begin(), saved.end());
qDebug().noquote().nospace()
<< "[PROFILE_STATE_WRITE]\n"
<< "reason = constructor\n"
<< "profile = " << name << "\n"
<< "count = " << m_profileStates[name].size();
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence
<< "m_profileStates write (constructor)"
<< "profile:" << name
<< "key:" << key
<< "modsCount:" << m_profileStates[name].size();
}
m_profileTabBar->blockSignals(false);
m_profileTabBar->setUsesScrollButtons(m_profileTabBar->count() > 1);
m_instance->settings()->getOrRegisterSetting(lastActiveIndexKey(), 0);
int savedIndex = m_instance->settings()->get(lastActiveIndexKey()).toInt();
@ -286,10 +219,6 @@ ModFolderPage::ModFolderPage(BaseInstance* inst, ModFolderModel* model, QWidget*
connect(m_model, &QAbstractItemModel::dataChanged, this, [this]() {
if (!m_applyingProfile) {
qDebug().noquote().nospace()
<< "[SAVE_TRIGGER]\n"
<< "source = dataChanged\n"
<< "currentProfile = " << m_currentProfile;
saveCurrentProfileState();
}
});
@ -672,20 +601,7 @@ inline bool ModFolderPage::handleNoModLoader()
void ModFolderPage::saveCurrentProfileState()
{
if (m_profileLoading) {
return;
}
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence << "saveCurrentProfileState() START"
<< "thread:" << QThread::currentThreadId()
<< "model:" << m_model
<< "profile:" << m_currentProfile
<< "destructorStarted:" << m_destructorStarted;
if (m_currentProfile.isEmpty()) {
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence << "saveCurrentProfileState() END (empty profile)"
<< "thread:" << QThread::currentThreadId()
<< "model:" << m_model;
return;
}
bool stillExists = false;
@ -696,10 +612,6 @@ void ModFolderPage::saveCurrentProfileState()
}
}
if (!stillExists) {
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence << "saveCurrentProfileState() END (profile no longer exists)"
<< "thread:" << QThread::currentThreadId()
<< "model:" << m_model
<< "profile:" << m_currentProfile;
return;
}
QSet<QString> enabledMods;
@ -710,41 +622,13 @@ void ModFolderPage::saveCurrentProfileState()
}
}
m_profileStates[m_currentProfile] = enabledMods;
qDebug().noquote().nospace()
<< "[PROFILE_STATE_WRITE]\n"
<< "reason = saveCurrentProfileState\n"
<< "profile = " << m_currentProfile << "\n"
<< "count = " << m_profileStates[m_currentProfile].size();
QString key = profileKey(m_currentProfile);
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence
<< "m_profileStates write (saveCurrentProfileState)"
<< "profile:" << m_currentProfile
<< "key:" << key
<< "modsCount:" << enabledMods.size();
m_instance->settings()->getOrRegisterSetting(key, QStringList());
m_instance->settings()->set(key, QStringList(enabledMods.begin(), enabledMods.end()));
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence
<< "settings()->set write (saveCurrentProfileState)"
<< "profile:" << m_currentProfile
<< "key:" << key
<< "modsCount:" << enabledMods.size();
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence << "saveCurrentProfileState() END (saved)"
<< "thread:" << QThread::currentThreadId()
<< "model:" << m_model
<< "profile:" << m_currentProfile
<< "savedModsCount:" << enabledMods.size();
}
void ModFolderPage::applyProfileSwitch(int index, int generation) {
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence << "onProfileTabChanged() START"
<< "index:" << index
<< "thread:" << QThread::currentThreadId()
<< "model:" << m_model
<< "profileBefore:" << m_currentProfile
<< "destructorStarted:" << m_destructorStarted;
if (m_currentProfile.isEmpty()) {
QVariant val = m_profileTabBar->property("currentProfileName");
m_currentProfile = val.isValid() ? val.toString() : QString();
@ -752,40 +636,21 @@ void ModFolderPage::applyProfileSwitch(int index, int generation) {
saveCurrentProfileState();
m_profileLoading = true;
if (index >= 0 && index < m_profileTabBar->count()) {
QString tabName = m_profileTabBar->tabText(index);
m_currentProfile = tabName;
setActiveProfileForModel(m_model, m_currentProfile);
m_profileTabBar->setProperty("currentProfileName", tabName);
m_instance->settings()->set(lastActiveIndexKey(), index);
QSet<QString> enabledMods;
if (m_profileStates.contains(tabName)) {
enabledMods = m_profileStates[tabName];
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence
<< "profile load (onProfileTabChanged): cached state read"
<< "thread:" << QThread::currentThreadId()
<< "model:" << m_model
<< "profile:" << tabName
<< "modsCount:" << enabledMods.size();
} else {
QString key = profileKey(tabName);
m_instance->settings()->getOrRegisterSetting(key, QStringList());
QStringList saved = m_instance->settings()->get(key).toStringList();
enabledMods = QSet<QString>(saved.begin(), saved.end());
m_profileStates[tabName] = enabledMods;
qDebug().noquote().nospace()
<< "[PROFILE_STATE_WRITE]\n"
<< "reason = onProfileTabChanged\n"
<< "profile = " << tabName << "\n"
<< "count = " << m_profileStates[tabName].size();
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence
<< "m_profileStates write (onProfileTabChanged - settings read)"
<< "profile:" << tabName
<< "key:" << key
<< "modsCount:" << enabledMods.size();
}
QModelIndexList toEnable;
@ -803,6 +668,7 @@ void ModFolderPage::applyProfileSwitch(int index, int generation) {
}
}
}
m_applyingProfile = true;
if (!toEnable.isEmpty()) {
m_model->setResourceEnabled(toEnable, EnableAction::ENABLE);
}
@ -810,12 +676,9 @@ void ModFolderPage::applyProfileSwitch(int index, int generation) {
m_model->setResourceEnabled(toDisable, EnableAction::DISABLE);
}
compareModelToProfileState("BEFORE update()", m_model, enabledMods, ++g_logSequence);
// Capture generation token. If tab changes again before this update
// completes, the token will be stale and we discard the result.
int capturedGeneration = generation;
m_applyingProfile = true;
connect(m_model, &ResourceFolderModel::updateFinished, this,
[this, capturedGeneration] {
if (capturedGeneration == m_profileSwitchGeneration) {
@ -827,33 +690,11 @@ void ModFolderPage::applyProfileSwitch(int index, int generation) {
m_model->update();
qDebug().noquote().nospace()
<< "[ProfileSwitch]\n"
<< "Profile: " << tabName << "\n"
<< "Enable: " << toEnable.size() << "\n"
<< "Disable: " << toDisable.size() << "\n"
<< "updateStarted: " << (started ? "true" : "false");
compareModelToProfileState("AFTER update()", m_model, enabledMods, ++g_logSequence);
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence
<< "EMIT m_model->dataChanged() (onProfileTabChanged layout update)"
<< "thread:" << QThread::currentThreadId()
<< "model:" << m_model
<< "profile:" << m_currentProfile;
emit m_model->dataChanged(m_model->index(0, 0), m_model->index(m_model->rowCount() - 1, m_model->columnCount(QModelIndex()) - 1));
} else {
m_currentProfile = QString();
setActiveProfileForModel(m_model, QStringLiteral("None"));
m_profileTabBar->setProperty("currentProfileName", QString());
m_profileLoading = false;
m_applyingProfile = false;
}
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence << "onProfileTabChanged() END"
<< "index:" << index
<< "thread:" << QThread::currentThreadId()
<< "model:" << m_model
<< "profileAfter:" << m_currentProfile;
}
@ -893,25 +734,10 @@ void ModFolderPage::createProfile(const QString& name, const QSet<QString>& init
// Persist state to memory and settings
m_profileStates[name] = initialState;
qDebug().noquote().nospace()
<< "[PROFILE_STATE_WRITE]\n"
<< "reason = createProfile\n"
<< "profile = " << name << "\n"
<< "count = " << m_profileStates[name].size();
QString key = profileKey(name);
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence
<< "m_profileStates write (createProfile)"
<< "profile:" << name
<< "key:" << key
<< "modsCount:" << initialState.size();
m_instance->settings()->getOrRegisterSetting(key, QStringList());
m_instance->settings()->set(key, QStringList(initialState.begin(), initialState.end()));
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence
<< "settings()->set write (createProfile)"
<< "profile:" << name
<< "key:" << key
<< "modsCount:" << initialState.size();
// Insert tab at the correct position
if (insertAfterIndex >= 0 && insertAfterIndex < m_profileTabBar->count()) {
@ -919,6 +745,7 @@ void ModFolderPage::createProfile(const QString& name, const QSet<QString>& init
} else {
m_profileTabBar->addTab(name);
}
m_profileTabBar->setUsesScrollButtons(m_profileTabBar->count() > 1);
saveProfileList();
}
@ -1007,16 +834,6 @@ void ModFolderPage::onTabDuplicate(int sourceIndex)
}
}
m_profileStates[m_currentProfile] = enabledMods;
qDebug().noquote().nospace()
<< "[PROFILE_STATE_WRITE]\n"
<< "reason = onTabDuplicate\n"
<< "profile = " << m_currentProfile << "\n"
<< "count = " << m_profileStates[m_currentProfile].size();
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence
<< "m_profileStates write (onTabDuplicate)"
<< "profile:" << m_currentProfile
<< "key:" << profileKey(m_currentProfile)
<< "modsCount:" << enabledMods.size();
}
QString sourceName = m_profileTabBar->tabText(sourceIndex);
@ -1056,16 +873,6 @@ void ModFolderPage::onTabRename(int tabIndex)
// Migrate in-memory state to the new key
if (m_profileStates.contains(oldName)) {
m_profileStates[newName] = m_profileStates.take(oldName);
qDebug().noquote().nospace()
<< "[PROFILE_STATE_WRITE]\n"
<< "reason = onTabRename\n"
<< "profile = " << newName << "\n"
<< "count = " << m_profileStates[newName].size();
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence
<< "m_profileStates write (onTabRename)"
<< "profile:" << newName
<< "key:" << profileKey(newName)
<< "modsCount:" << m_profileStates[newName].size();
}
// Migrate settings: read → reset old key → write under new key
@ -1075,11 +882,6 @@ void ModFolderPage::onTabRename(int tabIndex)
m_instance->settings()->reset(oldKey);
m_instance->settings()->getOrRegisterSetting(newKey, QStringList());
m_instance->settings()->set(newKey, stateData);
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence
<< "settings()->set write (onTabRename)"
<< "profile:" << newName
<< "key:" << newKey
<< "modsCount:" << stateData.size();
// Update the visible tab label
m_profileTabBar->setTabText(tabIndex, newName);
@ -1109,14 +911,11 @@ void ModFolderPage::onTabRemove(int tabIndex)
if (response != QMessageBox::Yes) return;
m_profileStates.remove(name);
qDebug().noquote().nospace()
<< "[PROFILE_STATE_WRITE]\n"
<< "reason = onTabRemove\n"
<< "profile = " << name << "\n"
<< "count = 0";
m_instance->settings()->reset(profileKey(name));
m_profileTabBar->removeTab(tabIndex);
m_profileTabBar->setUsesScrollButtons(m_profileTabBar->count() > 1);
saveProfileList();
}
@ -1124,9 +923,9 @@ void ModFolderPage::onTabEnableAll(int tabIndex)
{
if (m_profileTabBar->currentIndex() != tabIndex) {
m_profileTabBar->setCurrentIndex(tabIndex);
} else {
applyProfileSwitch(tabIndex, m_profileSwitchGeneration);
}
applyProfileSwitch(tabIndex, m_profileSwitchGeneration);
// Build the full index list and enable every mod in the active profile.
QModelIndexList allIndices;
allIndices.reserve(m_model->rowCount());
@ -1143,9 +942,9 @@ void ModFolderPage::onTabDisableAll(int tabIndex)
{
if (m_profileTabBar->currentIndex() != tabIndex) {
m_profileTabBar->setCurrentIndex(tabIndex);
} else {
applyProfileSwitch(tabIndex, m_profileSwitchGeneration);
}
applyProfileSwitch(tabIndex, m_profileSwitchGeneration);
// Build the full index list and disable every mod in the active profile.
QModelIndexList allIndices;
allIndices.reserve(m_model->rowCount());

View file

@ -120,7 +120,6 @@ class ModFolderPage : public ExternalResourcesPage {
QString m_currentProfile;
QString m_settingsPrefix;
bool m_destructorStarted = false;
bool m_profileLoading = false;
int m_profileSwitchGeneration = 0;
bool m_applyingProfile = false;
};