diff options
| author | Jeremy Rimpo <jeremy.rimpo@servermonkey.com> | 2023-09-19 11:19:39 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-09-19 18:19:39 +0200 |
| commit | 70509275405d2a5c5e94743786f03b17ef2051f2 (patch) | |
| tree | e98fb95afcd9e8ce499ff02351e3ad963a9c76f8 /src | |
| parent | 59b5b1cfca1614df681055d98d602692f482f0e2 (diff) | |
Default profile settings (#1869)
* Fix archive parsing and BSA invalidation
Diffstat (limited to 'src')
| -rw-r--r-- | src/createinstancedialog.cpp | 18 | ||||
| -rw-r--r-- | src/createinstancedialog.h | 10 | ||||
| -rw-r--r-- | src/createinstancedialog.ui | 90 | ||||
| -rw-r--r-- | src/createinstancedialogpages.cpp | 33 | ||||
| -rw-r--r-- | src/createinstancedialogpages.h | 19 | ||||
| -rw-r--r-- | src/profile.cpp | 48 | ||||
| -rw-r--r-- | src/settings.cpp | 30 | ||||
| -rw-r--r-- | src/settings.h | 15 | ||||
| -rw-r--r-- | src/settingsdialog.ui | 44 | ||||
| -rw-r--r-- | src/settingsdialoggeneral.cpp | 11 |
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><h3>Configure your profile settings.</h3></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( |
