summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJeremy Rimpo <jeremy.rimpo@servermonkey.com>2023-09-19 11:19:39 -0500
committerGitHub <noreply@github.com>2023-09-19 18:19:39 +0200
commit70509275405d2a5c5e94743786f03b17ef2051f2 (patch)
treee98fb95afcd9e8ce499ff02351e3ad963a9c76f8 /src
parent59b5b1cfca1614df681055d98d602692f482f0e2 (diff)
Default profile settings (#1869)
* Fix archive parsing and BSA invalidation
Diffstat (limited to 'src')
-rw-r--r--src/createinstancedialog.cpp18
-rw-r--r--src/createinstancedialog.h10
-rw-r--r--src/createinstancedialog.ui90
-rw-r--r--src/createinstancedialogpages.cpp33
-rw-r--r--src/createinstancedialogpages.h19
-rw-r--r--src/profile.cpp48
-rw-r--r--src/settings.cpp30
-rw-r--r--src/settings.h15
-rw-r--r--src/settingsdialog.ui44
-rw-r--r--src/settingsdialoggeneral.cpp11
10 files changed, 290 insertions, 28 deletions
diff --git a/src/createinstancedialog.cpp b/src/createinstancedialog.cpp
index c5f51e0e..d50a2063 100644
--- a/src/createinstancedialog.cpp
+++ b/src/createinstancedialog.cpp
@@ -110,6 +110,7 @@ CreateInstanceDialog::CreateInstanceDialog(const PluginContainer& pc, Settings*
m_pages.push_back(std::make_unique<GamePage>(*this));
m_pages.push_back(std::make_unique<VariantsPage>(*this));
m_pages.push_back(std::make_unique<NamePage>(*this));
+ m_pages.push_back(std::make_unique<ProfilePage>(*this));
m_pages.push_back(std::make_unique<PathsPage>(*this));
m_pages.push_back(std::make_unique<NexusPage>(*this));
m_pages.push_back(std::make_unique<ConfirmationPage>(*this));
@@ -355,6 +356,10 @@ void CreateInstanceDialog::finish()
s.paths().setOverwrite(ci.paths.overwrite);
}
+ s.setProfileLocalInis(ci.profileSettings.localInis);
+ s.setProfileLocalSaves(ci.profileSettings.localSaves);
+ s.setProfileArchiveInvalidation(ci.profileSettings.archiveInvalidation);
+
logCreation(tr("Writing %1...").arg(ci.iniPath));
// writing ini
@@ -475,12 +480,13 @@ CreateInstanceDialog::CreationInfo CreateInstanceDialog::rawCreationInfo() const
CreationInfo ci;
- ci.type = getSelected(&cid::Page::selectedInstanceType);
- ci.game = getSelected(&cid::Page::selectedGame);
- ci.gameLocation = getSelected(&cid::Page::selectedGameLocation);
- ci.gameVariant = getSelected(&cid::Page::selectedGameVariant, ci.game);
- ci.instanceName = getSelected(&cid::Page::selectedInstanceName);
- ci.paths = getSelected(&cid::Page::selectedPaths);
+ ci.type = getSelected(&cid::Page::selectedInstanceType);
+ ci.game = getSelected(&cid::Page::selectedGame);
+ ci.gameLocation = getSelected(&cid::Page::selectedGameLocation);
+ ci.gameVariant = getSelected(&cid::Page::selectedGameVariant, ci.game);
+ ci.instanceName = getSelected(&cid::Page::selectedInstanceName);
+ ci.profileSettings = getSelected(&cid::Page::profileSettings);
+ ci.paths = getSelected(&cid::Page::selectedPaths);
if (ci.type == Portable) {
ci.dataPath = QDir(InstanceManager::singleton().portablePath()).absolutePath();
diff --git a/src/createinstancedialog.h b/src/createinstancedialog.h
index fe3c5646..4495cc78 100644
--- a/src/createinstancedialog.h
+++ b/src/createinstancedialog.h
@@ -66,6 +66,15 @@ public:
auto operator<=>(const Paths&) const = default;
};
+ struct ProfileSettings
+ {
+ bool localInis;
+ bool localSaves;
+ bool archiveInvalidation;
+
+ auto operator<=>(const ProfileSettings&) const = default;
+ };
+
// all the info filled in the various pages
//
struct CreationInfo
@@ -78,6 +87,7 @@ public:
QString dataPath;
QString iniPath;
Paths paths;
+ ProfileSettings profileSettings;
};
CreateInstanceDialog(const PluginContainer& pc, Settings* s,
diff --git a/src/createinstancedialog.ui b/src/createinstancedialog.ui
index 5c791aff..b4750755 100644
--- a/src/createinstancedialog.ui
+++ b/src/createinstancedialog.ui
@@ -34,7 +34,6 @@
<property name="font">
<font>
<pointsize>14</pointsize>
- <weight>75</weight>
<bold>true</bold>
</font>
</property>
@@ -294,7 +293,7 @@
<x>0</x>
<y>0</y>
<width>455</width>
- <height>286</height>
+ <height>275</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_26">
@@ -430,7 +429,7 @@
<x>0</x>
<y>0</y>
<width>455</width>
- <height>278</height>
+ <height>265</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_17">
@@ -546,6 +545,90 @@
</item>
</layout>
</widget>
+ <widget class="QWidget" name="page">
+ <layout class="QVBoxLayout" name="verticalLayout_31">
+ <item>
+ <widget class="QWidget" name="widget_24" native="true">
+ <layout class="QHBoxLayout" name="horizontalLayout_8">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="profileSettingsLabel">
+ <property name="text">
+ <string>&lt;h3&gt;Configure your profile settings.&lt;/h3&gt;</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QWidget" name="widget_25" native="true">
+ <layout class="QVBoxLayout" name="verticalLayout_28">
+ <item>
+ <widget class="QCheckBox" name="profileInisCheckbox">
+ <property name="toolTip">
+ <string extracomment="Enabling this will copy your game's INI files into each profile, which will override the default INI settings"/>
+ </property>
+ <property name="text">
+ <string>Use profile-specific game INI files</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="profileSavesCheckbox">
+ <property name="toolTip">
+ <string extracomment="Enabling this will redirect the game's save files into your active profile, allowing you to separate your saves between profiles"/>
+ </property>
+ <property name="text">
+ <string>Use profile-specific save games</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="archiveInvalidationCheckbox">
+ <property name="toolTip">
+ <string extracomment="Enabling this will allow MO2 to automatically run necessary INI edits or other steps to allow file overrides in the game."/>
+ </property>
+ <property name="text">
+ <string>Automatic archive invalidation</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_7">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
<widget class="QWidget" name="page_6">
<layout class="QVBoxLayout" name="verticalLayout_14">
<item>
@@ -1242,7 +1325,6 @@
<tabstop>showAllGames</tabstop>
<tabstop>gamesFilter</tabstop>
<tabstop>scrollArea_2</tabstop>
- <tabstop>instanceName</tabstop>
<tabstop>location</tabstop>
<tabstop>browseLocation</tabstop>
<tabstop>advancedPathOptions</tabstop>
diff --git a/src/createinstancedialogpages.cpp b/src/createinstancedialogpages.cpp
index c8cec45f..27bd4062 100644
--- a/src/createinstancedialogpages.cpp
+++ b/src/createinstancedialogpages.cpp
@@ -143,6 +143,12 @@ CreateInstanceDialog::Paths Page::selectedPaths() const
return {};
}
+CreateInstanceDialog::ProfileSettings Page::profileSettings() const
+{
+ // no-op
+ return {};
+}
+
IntroPage::IntroPage(CreateInstanceDialog& dlg)
: Page(dlg), m_skip(GlobalSettings::hideCreateInstanceIntro())
{
@@ -931,6 +937,22 @@ bool NamePage::checkName(QString parentDir, QString name)
return okay;
}
+ProfilePage::ProfilePage(CreateInstanceDialog& dlg) : Page(dlg) {}
+
+bool ProfilePage::ready() const
+{
+ return true;
+}
+
+CreateInstanceDialog::ProfileSettings ProfilePage::profileSettings() const
+{
+ CreateInstanceDialog::ProfileSettings profileSettings;
+ profileSettings.localInis = ui->profileInisCheckbox->isChecked();
+ profileSettings.localSaves = ui->profileSavesCheckbox->isChecked();
+ profileSettings.archiveInvalidation = ui->archiveInvalidationCheckbox->isChecked();
+ return profileSettings;
+}
+
PathsPage::PathsPage(CreateInstanceDialog& dlg)
: Page(dlg), m_lastType(CreateInstanceDialog::NoType), m_label(ui->pathsLabel),
m_simpleExists(ui->locationExists), m_simpleInvalid(ui->locationInvalid),
@@ -1215,6 +1237,17 @@ QString ConfirmationPage::makeReview() const
lines.push_back(QObject::tr("Instance name: %1").arg(ci.instanceName));
}
+ lines.push_back(QObject::tr("Profile settings:"));
+ lines.push_back(
+ QObject::tr(" Local INIs: %1")
+ .arg(ci.profileSettings.localInis ? QObject::tr("yes") : QObject::tr("no")));
+ lines.push_back(
+ QObject::tr(" Local Saves: %1")
+ .arg(ci.profileSettings.localSaves ? QObject::tr("yes") : QObject::tr("no")));
+ lines.push_back(QObject::tr(" Automatic Archive Invalidation: %1")
+ .arg(ci.profileSettings.archiveInvalidation ? QObject::tr("yes")
+ : QObject::tr("no")));
+
if (ci.paths.downloads.isEmpty()) {
// simple settings
if (ci.paths.base != ci.dataPath) {
diff --git a/src/createinstancedialogpages.h b/src/createinstancedialogpages.h
index d9751a52..ce525635 100644
--- a/src/createinstancedialogpages.h
+++ b/src/createinstancedialogpages.h
@@ -110,6 +110,10 @@ public:
//
virtual CreateInstanceDialog::Paths selectedPaths() const;
+ // returns the profile settings
+ //
+ virtual CreateInstanceDialog::ProfileSettings profileSettings() const;
+
protected:
Ui::CreateInstanceDialog* ui;
CreateInstanceDialog& m_dlg;
@@ -557,6 +561,21 @@ private:
void setIfEmpty(QLineEdit* e, const QString& path, bool force);
};
+// default settings for profiles page; allow the user to set their preferred
+// defaults for the profile options
+//
+class ProfilePage : public Page
+{
+public:
+ ProfilePage(CreateInstanceDialog& dlg);
+
+ // always returns true, options are boolean
+ //
+ bool ready() const override;
+
+ CreateInstanceDialog::ProfileSettings profileSettings() const override;
+};
+
// nexus connection page; this reuses the ui found in the settings dialog and
// is skipped if there's already an api key in the credentials manager
//
diff --git a/src/profile.cpp b/src/profile.cpp
index c5ea5eec..d4299a7b 100644
--- a/src/profile.cpp
+++ b/src/profile.cpp
@@ -157,22 +157,36 @@ void Profile::findProfileSettings()
{
if (setting("", "LocalSaves") == QVariant()) {
if (m_Directory.exists("saves")) {
- storeSetting("", "LocalSaves", true);
+ if (!Settings::instance().profileLocalSaves()) {
+ m_Directory.rename("saves", "_saves");
+ storeSetting("", "LocalSaves", false);
+ } else {
+ storeSetting("", "LocalSaves", true);
+ }
} else {
if (m_Directory.exists("_saves")) {
- m_Directory.rename("_saves", "saves");
+ if (Settings::instance().profileLocalSaves()) {
+ m_Directory.rename("_saves", "saves");
+ storeSetting("", "LocalSaves", true);
+ } else {
+ storeSetting("", "LocalSaves", false);
+ }
+ } else {
+ storeSetting("", "LocalSaves", Settings::instance().profileLocalSaves());
}
- storeSetting("", "LocalSaves", false);
}
}
if (setting("", "LocalSettings") == QVariant()) {
QString backupFile = getIniFileName() + "_";
if (m_Directory.exists(backupFile)) {
- storeSetting("", "LocalSettings", false);
+ storeSetting("", "LocalSettings", true);
m_Directory.rename(backupFile, getIniFileName());
- } else {
+ } else if (Settings::instance().profileLocalInis()) {
storeSetting("", "LocalSettings", true);
+ enableLocalSettings(true);
+ } else {
+ storeSetting("", "LocalSettings", false);
}
}
@@ -183,14 +197,23 @@ void Profile::findProfileSettings()
if ((invalidation != nullptr) && (dataArchives != nullptr)) {
for (const QString& archive : dataArchives->archives(this)) {
if (invalidation->isInvalidationBSA(archive)) {
- storeSetting("", "AutomaticArchiveInvalidation", true);
found = true;
break;
}
}
}
- if (!found) {
- storeSetting("", "AutomaticArchiveInvalidation", false);
+ if (found) {
+ if (!Settings::instance().profileArchiveInvalidation()) {
+ deactivateInvalidation();
+ } else {
+ storeSetting("", "AutomaticArchiveInvalidation", true);
+ }
+ } else {
+ if (Settings::instance().profileArchiveInvalidation()) {
+ activateInvalidation();
+ } else {
+ storeSetting("", "AutomaticArchiveInvalidation", false);
+ }
}
}
}
@@ -795,7 +818,9 @@ bool Profile::invalidationActive(bool* supported) const
*supported = ((invalidation != nullptr) && (dataArchives != nullptr));
}
- return setting("", "AutomaticArchiveInvalidation", false).toBool();
+ return setting("", "AutomaticArchiveInvalidation",
+ Settings::instance().profileArchiveInvalidation())
+ .toBool();
}
void Profile::deactivateInvalidation()
@@ -822,7 +847,7 @@ void Profile::activateInvalidation()
bool Profile::localSavesEnabled() const
{
- return setting("", "LocalSaves", false).toBool();
+ return setting("", "LocalSaves", Settings::instance().profileLocalSaves()).toBool();
}
bool Profile::enableLocalSaves(bool enable)
@@ -856,7 +881,8 @@ bool Profile::enableLocalSaves(bool enable)
bool Profile::localSettingsEnabled() const
{
- bool enabled = setting("", "LocalSettings", false).toBool();
+ bool enabled =
+ setting("", "LocalSettings", Settings::instance().profileLocalInis()).toBool();
if (enabled) {
QStringList missingFiles;
for (QString file : m_GamePlugin->iniFiles()) {
diff --git a/src/settings.cpp b/src/settings.cpp
index fc9985f4..b568d802 100644
--- a/src/settings.cpp
+++ b/src/settings.cpp
@@ -214,6 +214,36 @@ void Settings::setUsePrereleases(bool b)
set(m_Settings, "Settings", "use_prereleases", b);
}
+bool Settings::profileLocalInis() const
+{
+ return get<bool>(m_Settings, "Settings", "profile_local_inis", true);
+}
+
+void Settings::setProfileLocalInis(bool b)
+{
+ set(m_Settings, "Settings", "profile_local_inis", b);
+}
+
+bool Settings::profileLocalSaves() const
+{
+ return get<bool>(m_Settings, "Settings", "profile_local_saves", false);
+}
+
+void Settings::setProfileLocalSaves(bool b)
+{
+ set(m_Settings, "Settings", "profile_local_saves", b);
+}
+
+bool Settings::profileArchiveInvalidation() const
+{
+ return get<bool>(m_Settings, "Settings", "profile_archive_invalidation", false);
+}
+
+void Settings::setProfileArchiveInvalidation(bool b)
+{
+ set(m_Settings, "Settings", "profile_archive_invalidation", b);
+}
+
bool Settings::useSplash() const
{
return get<bool>(m_Settings, "Settings", "use_splash", true);
diff --git a/src/settings.h b/src/settings.h
index 6a11d662..34a8669a 100644
--- a/src/settings.h
+++ b/src/settings.h
@@ -810,6 +810,21 @@ public:
bool usePrereleases() const;
void setUsePrereleases(bool b);
+ // whether profiles should default to local INIs
+ //
+ bool profileLocalInis() const;
+ void setProfileLocalInis(bool b);
+
+ // whether profiles should default to local saves
+ //
+ bool profileLocalSaves() const;
+ void setProfileLocalSaves(bool b);
+
+ // whether profiles should default to automatic archive invalidation
+ //
+ bool profileArchiveInvalidation() const;
+ void setProfileArchiveInvalidation(bool b);
+
// whether to use spascreen or not
//
bool useSplash() const;
diff --git a/src/settingsdialog.ui b/src/settingsdialog.ui
index a4c9cc7e..27949c3a 100644
--- a/src/settingsdialog.ui
+++ b/src/settingsdialog.ui
@@ -23,7 +23,7 @@
<attribute name="title">
<string>General</string>
</attribute>
- <layout class="QGridLayout" name="gridLayout" rowstretch="0,0,0">
+ <layout class="QGridLayout" name="gridLayout" rowstretch="0">
<item row="0" column="0">
<widget class="QScrollArea" name="generalScrollArea">
<property name="styleSheet">
@@ -44,8 +44,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>780</width>
- <height>502</height>
+ <width>761</width>
+ <height>550</height>
</rect>
</property>
<property name="autoFillBackground">
@@ -205,6 +205,36 @@
</widget>
</item>
<item>
+ <widget class="QGroupBox" name="groupBox_8">
+ <property name="title">
+ <string>Profile Defaults</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_11">
+ <item>
+ <widget class="QCheckBox" name="localINIs">
+ <property name="text">
+ <string>Local INIs</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="localSaves">
+ <property name="text">
+ <string>Local Saves</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="automaticArchiveInvalidation">
+ <property name="text">
+ <string>Automatic Archive Invalidation</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
<widget class="QGroupBox" name="groupBox_9">
<property name="title">
<string>Miscellaneous</string>
@@ -1022,8 +1052,8 @@ If you disable this feature, MO will only display official DLCs this way. Please
<rect>
<x>0</x>
<y>0</y>
- <width>780</width>
- <height>502</height>
+ <width>778</width>
+ <height>497</height>
</rect>
</property>
<property name="autoFillBackground">
@@ -1702,8 +1732,8 @@ If you disable this feature, MO will only display official DLCs this way. Please
<rect>
<x>0</x>
<y>0</y>
- <width>780</width>
- <height>483</height>
+ <width>778</width>
+ <height>475</height>
</rect>
</property>
<property name="autoFillBackground">
diff --git a/src/settingsdialoggeneral.cpp b/src/settingsdialoggeneral.cpp
index 95655ac8..7acaa190 100644
--- a/src/settingsdialoggeneral.cpp
+++ b/src/settingsdialoggeneral.cpp
@@ -25,6 +25,11 @@ GeneralSettingsTab::GeneralSettingsTab(Settings& s, SettingsDialog& d)
ui->checkForUpdates->setChecked(settings().checkForUpdates());
ui->usePrereleaseBox->setChecked(settings().usePrereleases());
+ // profile defaults
+ ui->localINIs->setChecked(settings().profileLocalInis());
+ ui->localSaves->setChecked(settings().profileLocalSaves());
+ ui->automaticArchiveInvalidation->setChecked(settings().profileArchiveInvalidation());
+
// miscellaneous
ui->centerDialogs->setChecked(settings().geometry().centerDialogs());
ui->changeGameConfirmation->setChecked(
@@ -64,6 +69,12 @@ void GeneralSettingsTab::update()
settings().setCheckForUpdates(ui->checkForUpdates->isChecked());
settings().setUsePrereleases(ui->usePrereleaseBox->isChecked());
+ // profile defaults
+ settings().setProfileLocalInis(ui->localINIs->isChecked());
+ settings().setProfileLocalSaves(ui->localSaves->isChecked());
+ settings().setProfileArchiveInvalidation(
+ ui->automaticArchiveInvalidation->isChecked());
+
// miscellaneous
settings().geometry().setCenterDialogs(ui->centerDialogs->isChecked());
settings().interface().setShowChangeGameConfirmation(