diff options
| author | isanae <14251494+isanae@users.noreply.github.com> | 2019-09-02 14:52:02 -0400 |
|---|---|---|
| committer | isanae <14251494+isanae@users.noreply.github.com> | 2019-09-02 14:52:02 -0400 |
| commit | e9dba260cb9548dd5863ac66da18c295f6499b92 (patch) | |
| tree | 8471d5fe53389dd8aebfb0cc57fcca014bcd4d70 /src | |
| parent | ec3fb7b3509fb10a8a1392740e209509ae6c092c (diff) | |
split settings into a bunch of classes
removed "get" from the getters that had it
Diffstat (limited to 'src')
30 files changed, 1554 insertions, 1268 deletions
diff --git a/src/browserdialog.cpp b/src/browserdialog.cpp index 70da0b9c..72cb8862 100644 --- a/src/browserdialog.cpp +++ b/src/browserdialog.cpp @@ -49,7 +49,7 @@ BrowserDialog::BrowserDialog(QWidget *parent) ui->setupUi(this);
m_AccessManager->setCookieJar(new PersistentCookieJar(
- QDir::fromNativeSeparators(Settings::instance().getCacheDirectory() + "/cookies.dat")));
+ QDir::fromNativeSeparators(Settings::instance().paths().cache() + "/cookies.dat")));
Qt::WindowFlags flags = windowFlags() | Qt::WindowMaximizeButtonHint | Qt::WindowMinimizeButtonHint;
Qt::WindowFlags helpFlag = Qt::WindowContextHelpButtonHint;
diff --git a/src/downloadlistsortproxy.cpp b/src/downloadlistsortproxy.cpp index 7bda139b..a69993c0 100644 --- a/src/downloadlistsortproxy.cpp +++ b/src/downloadlistsortproxy.cpp @@ -110,7 +110,7 @@ bool DownloadListSortProxy::filterAcceptsRow(int sourceRow, const QModelIndex&) if (m_CurrentFilter.length() == 0) {
return true;
} else if (sourceRow < m_Manager->numTotalDownloads()) {
- QString displayedName = Settings::instance().metaDownloads()
+ QString displayedName = Settings::instance().interface().metaDownloads()
? m_Manager->getDisplayName(sourceRow)
: m_Manager->getFileName(sourceRow);
return displayedName.contains(m_CurrentFilter, Qt::CaseInsensitive);
diff --git a/src/downloadmanager.cpp b/src/downloadmanager.cpp index a5dc164c..56238ef3 100644 --- a/src/downloadmanager.cpp +++ b/src/downloadmanager.cpp @@ -1731,7 +1731,7 @@ void DownloadManager::nxmDownloadURLsAvailable(QString gameName, int modID, int return; } - const auto servers = m_OrganizerCore->settings().getServers(); + const auto servers = m_OrganizerCore->settings().network().servers(); std::sort( resultList.begin(), diff --git a/src/executableslist.cpp b/src/executableslist.cpp index f2df2d6d..dce9181b 100644 --- a/src/executableslist.cpp +++ b/src/executableslist.cpp @@ -75,7 +75,7 @@ void ExecutablesList::load(const MOBase::IPluginGame* game, const Settings& s) // executables from 2.2.0, see upgradeFromCustom()
bool needsUpgrade = false;
- for (auto& map : s.getExecutables()) {
+ for (auto& map : s.executables()) {
Executable::Flags flags;
if (map["toolbar"].toBool())
diff --git a/src/filedialogmemory.cpp b/src/filedialogmemory.cpp index 96587ac7..8cfeb6b5 100644 --- a/src/filedialogmemory.cpp +++ b/src/filedialogmemory.cpp @@ -25,12 +25,12 @@ static std::map<QString, QString> g_Cache; void FileDialogMemory::save(Settings& s)
{
- s.setRecentDirectories(g_Cache);
+ s.paths().setRecent(g_Cache);
}
void FileDialogMemory::restore(const Settings& s)
{
- g_Cache = s.getRecentDirectories();
+ g_Cache = s.paths().recent();
}
QString FileDialogMemory::getOpenFileName(
diff --git a/src/main.cpp b/src/main.cpp index aa781c19..b5568fec 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -246,7 +246,7 @@ static bool HaveWriteAccess(const std::wstring &path) QString determineProfile(QStringList &arguments, const Settings &settings) { - auto selectedProfileName = settings.getSelectedProfileName(); + auto selectedProfileName = settings.game().selectedProfileName(); { // see if there is a profile on the command line int profileIndex = arguments.indexOf("-p", 1); @@ -271,12 +271,12 @@ QString determineProfile(QStringList &arguments, const Settings &settings) MOBase::IPluginGame *selectGame( Settings &settings, QDir const &gamePath, MOBase::IPluginGame *game) { - settings.setManagedGameName(game->gameName()); + settings.game().setName(game->gameName()); QString gameDir = gamePath.absolutePath(); game->setGamePath(gameDir); - settings.setManagedGameDirectory(gameDir); + settings.game().setDirectory(gameDir); return game; } @@ -289,7 +289,7 @@ MOBase::IPluginGame *determineCurrentGame( //user has done something odd. //If the game name has been set up, try to use that. - const auto gameName = settings.getManagedGameName(); + const auto gameName = settings.game().name(); const bool gameConfigured = (gameName.has_value() && *gameName != ""); if (gameConfigured) { @@ -299,7 +299,7 @@ MOBase::IPluginGame *determineCurrentGame( return nullptr; } - auto gamePath = settings.getManagedGameDirectory(); + auto gamePath = settings.game().directory(); if (!gamePath || *gamePath == "") { gamePath = game->gameDirectory().absolutePath(); } @@ -320,7 +320,7 @@ MOBase::IPluginGame *determineCurrentGame( //If we've made it this far and the instance is already configured for a game, something has gone wrong. //Tell the user about it. if (gameConfigured) { - const auto gamePath = settings.getManagedGameDirectory(); + const auto gamePath = settings.game().directory(); reportError( QObject::tr("Could not use configuration settings for game \"%1\", path \"%2\".") @@ -570,11 +570,11 @@ int runApplication(MOApplication &application, SingleInstance &instance, log::info("working directory: {}", QDir::currentPath()); Settings settings(dataPath + "/" + QString::fromStdWString(AppConfig::iniFileName())); - log::getDefault().setLevel(settings.logLevel()); + log::getDefault().setLevel(settings.diagnostics().logLevel()); // global crashDumpType sits in OrganizerCore to make a bit less ugly to // update it when the settings are changed during runtime - OrganizerCore::setGlobalCrashDumpsType(settings.crashDumpsType()); + OrganizerCore::setGlobalCrashDumpsType(settings.diagnostics().crashDumpsType()); env::Environment env; @@ -621,7 +621,7 @@ int runApplication(MOApplication &application, SingleInstance &instance, QString edition; - if (auto v=settings.getManagedGameEdition()) { + if (auto v=settings.game().edition()) { edition = *v; } else { QStringList editions = game->gameVariants(); @@ -640,7 +640,7 @@ int runApplication(MOApplication &application, SingleInstance &instance, return 1; } else { edition = selection.getChoiceString(); - settings.setManagedGameEdition(edition); + settings.game().setEdition(edition); } } } @@ -702,7 +702,7 @@ int runApplication(MOApplication &application, SingleInstance &instance, splash.activateWindow(); QString apiKey; - if (settings.getNexusApiKey(apiKey)) { + if (settings.nexus().apiKey(apiKey)) { NexusInterface::instance(&pluginContainer)->getAccessManager()->apiCheck(apiKey); } @@ -712,9 +712,9 @@ int runApplication(MOApplication &application, SingleInstance &instance, + QString::fromStdWString(AppConfig::tutorialsPath()) + "/", &organizer); - if (!application.setStyleFile(settings.getStyleName().value_or(""))) { + if (!application.setStyleFile(settings.interface().styleName().value_or(""))) { // disable invalid stylesheet - settings.setStyleName(""); + settings.interface().setStyleName(""); } int res = 1; diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 42b19cb7..657c1a27 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -222,8 +222,8 @@ MainWindow::MainWindow(Settings &settings { QWebEngineProfile::defaultProfile()->setPersistentCookiesPolicy(QWebEngineProfile::NoPersistentCookies); QWebEngineProfile::defaultProfile()->setHttpCacheMaximumSize(52428800); - QWebEngineProfile::defaultProfile()->setCachePath(settings.getCacheDirectory()); - QWebEngineProfile::defaultProfile()->setPersistentStoragePath(settings.getCacheDirectory()); + QWebEngineProfile::defaultProfile()->setCachePath(settings.paths().cache()); + QWebEngineProfile::defaultProfile()->setPersistentStoragePath(settings.paths().cache()); ui->setupUi(this); ui->statusBar->setup(ui); @@ -253,7 +253,7 @@ MainWindow::MainWindow(Settings &settings ui->statusBar->setAPI(ni->getAPIStats(), ni->getAPIUserAccount()); } - languageChange(settings.language()); + languageChange(settings.interface().language()); m_CategoryFactory.loadCategories(); @@ -1194,7 +1194,7 @@ void MainWindow::hookUpWindowTutorials() QString firstLine = QString::fromUtf8(file.readLine()); if (firstLine.startsWith("//WIN")) { QString windowName = firstLine.mid(6).trimmed(); - if (!m_OrganizerCore.settings().isTutorialCompleted(windowName)) { + if (!m_OrganizerCore.settings().interface().isTutorialCompleted(windowName)) { TutorialManager::instance().activateTutorial(windowName, fileName); } } @@ -1225,7 +1225,7 @@ void MainWindow::showEvent(QShowEvent *event) hookUpWindowTutorials(); - if (m_OrganizerCore.settings().getFirstStart()) { + if (m_OrganizerCore.settings().firstStart()) { QString firstStepsTutorial = ToQString(AppConfig::firstStepsTutorial()); if (TutorialManager::instance().hasTutorial(firstStepsTutorial)) { if (QMessageBox::question(this, tr("Show tutorial?"), @@ -1247,11 +1247,11 @@ void MainWindow::showEvent(QShowEvent *event) m_OrganizerCore.settings().setFirstStart(false); } - m_OrganizerCore.settings().restoreIndex(ui->groupCombo); + m_OrganizerCore.settings().widgets().restoreIndex(ui->groupCombo); allowListResize(); - m_OrganizerCore.settings().registerAsNXMHandler(false); + m_OrganizerCore.settings().nexus().registerAsNXMHandler(false); m_WasVisible = true; updateProblemsButton(); } @@ -1751,7 +1751,7 @@ bool MainWindow::refreshProfiles(bool selectProfile) profileBox->clear(); profileBox->addItem(QObject::tr("<Manage...>")); - QDir profilesDir(Settings::instance().getProfileDirectory()); + QDir profilesDir(Settings::instance().paths().profiles()); profilesDir.setFilter(QDir::AllDirs | QDir::NoDotAndDotDot); QDirIterator profileIter(profilesDir); @@ -1990,7 +1990,7 @@ void MainWindow::updateBSAList(const QStringList &defaultArchives, const QString newItem->setFlags(newItem->flags() & ~(Qt::ItemIsDropEnabled | Qt::ItemIsUserCheckable)); newItem->setCheckState(0, (index != -1) ? Qt::Checked : Qt::Unchecked); newItem->setData(0, Qt::UserRole, false); - if (m_OrganizerCore.settings().forceEnableCoreFiles() + if (m_OrganizerCore.settings().game().forceEnableCoreFiles() && defaultArchives.contains(fileInfo.fileName())) { newItem->setCheckState(0, Qt::Checked); newItem->setDisabled(true); @@ -2140,7 +2140,7 @@ void MainWindow::readSettings(const Settings& settings) { // special case in case someone puts 0 in the INI - auto v = settings.getIndex(ui->executablesListBox); + auto v = settings.widgets().index(ui->executablesListBox); if (!v || v == 0) { v = 1; } @@ -2148,7 +2148,7 @@ void MainWindow::readSettings(const Settings& settings) ui->executablesListBox->setCurrentIndex(*v); } - settings.restoreIndex(ui->groupCombo); + settings.widgets().restoreIndex(ui->groupCombo); { settings.geometry().restoreVisibility(ui->categoriesGroup, false); @@ -2157,7 +2157,7 @@ void MainWindow::readSettings(const Settings& settings) ui->displayCategoriesBtn->setChecked(v); } - if (settings.getUseProxy()) { + if (settings.network().useProxy()) { activateProxy(true); } } @@ -2165,12 +2165,12 @@ void MainWindow::readSettings(const Settings& settings) void MainWindow::processUpdates(Settings& settings) { const auto earliest = QVersionNumber::fromString("2.1.2").normalized(); - const auto lastVersion = settings.getVersion().value_or(earliest); + const auto lastVersion = settings.version().value_or(earliest); const auto currentVersion = m_OrganizerCore.getVersion().asQVersionNumber(); settings.processUpdates(currentVersion, lastVersion); - if (!settings.getFirstStart()) { + if (!settings.firstStart()) { if (lastVersion < QVersionNumber(2, 1, 3)) { bool lastHidden = true; for (int i = ModList::COL_GAME; i < ui->modList->model()->columnCount(); ++i) { @@ -2222,8 +2222,8 @@ void MainWindow::storeSettings(Settings& s) s.geometry().saveState(ui->downloadView->header()); s.geometry().saveState(ui->modList->header()); - s.saveIndex(ui->groupCombo); - s.saveIndex(ui->executablesListBox); + s.widgets().saveIndex(ui->groupCombo); + s.widgets().saveIndex(ui->executablesListBox); } ILockedWaitingForProcess* MainWindow::lock() @@ -2751,7 +2751,7 @@ void MainWindow::restoreBackup_clicked() ModInfo::Ptr modInfo = ModInfo::getByIndex(m_ContextRow); if (backupRegEx.indexIn(modInfo->name()) != -1) { QString regName = backupRegEx.cap(1); - QDir modDir(QDir::fromNativeSeparators(m_OrganizerCore.settings().getModDirectory())); + QDir modDir(QDir::fromNativeSeparators(m_OrganizerCore.settings().paths().mods())); if (!modDir.exists(regName) || (QMessageBox::question(this, tr("Overwrite?"), tr("This will replace the existing mod \"%1\". Continue?").arg(regName), @@ -2759,7 +2759,7 @@ void MainWindow::restoreBackup_clicked() if (modDir.exists(regName) && !shellDelete(QStringList(modDir.absoluteFilePath(regName)))) { reportError(tr("failed to remove mod \"%1\"").arg(regName)); } else { - QString destinationPath = QDir::fromNativeSeparators(m_OrganizerCore.settings().getModDirectory()) + "/" + regName; + QString destinationPath = QDir::fromNativeSeparators(m_OrganizerCore.settings().paths().mods()) + "/" + regName; if (!modDir.rename(modInfo->absolutePath(), destinationPath)) { reportError(tr("failed to rename \"%1\" to \"%2\"").arg(modInfo->absolutePath()).arg(destinationPath)); } @@ -3015,7 +3015,7 @@ void MainWindow::untrack_clicked() void MainWindow::windowTutorialFinished(const QString &windowName) { - m_OrganizerCore.settings().setTutorialCompleted(windowName); + m_OrganizerCore.settings().interface().setTutorialCompleted(windowName); } void MainWindow::overwriteClosed(int) @@ -3645,7 +3645,7 @@ void MainWindow::createSeparator_clicked() m_OrganizerCore.modList()->changeModPriority(ModInfo::getIndex(name), newPriority); } - if (auto c=m_OrganizerCore.settings().getPreviousSeparatorColor()) { + if (auto c=m_OrganizerCore.settings().colors().previousSeparatorColor()) { ModInfo::getByIndex(ModInfo::getIndex(name))->setColor(*c); } } @@ -3662,7 +3662,7 @@ void MainWindow::setColor_clicked() if (currentColor.isValid()) { dialog.setCurrentColor(currentColor); } - else if (auto c=settings.getPreviousSeparatorColor()) { + else if (auto c=settings.colors().previousSeparatorColor()) { dialog.setCurrentColor(*c); } @@ -3673,7 +3673,7 @@ void MainWindow::setColor_clicked() if (!currentColor.isValid()) return; - settings.setPreviousSeparatorColor(currentColor); + settings.colors().setPreviousSeparatorColor(currentColor); QItemSelectionModel *selection = ui->modList->selectionModel(); if (selection->hasSelection() && selection->selectedRows().count() > 1) { @@ -3710,7 +3710,7 @@ void MainWindow::resetColor_clicked() modInfo->setColor(color); } - m_OrganizerCore.settings().removePreviousSeparatorColor(); + m_OrganizerCore.settings().colors().removePreviousSeparatorColor(); } void MainWindow::createModFromOverwrite() @@ -4184,7 +4184,7 @@ void MainWindow::checkModsForUpdates() NexusInterface::instance(&m_PluginContainer)->requestTrackingInfo(this, QVariant(), QString()); } else { QString apiKey; - if (m_OrganizerCore.settings().getNexusApiKey(apiKey)) { + if (m_OrganizerCore.settings().nexus().apiKey(apiKey)) { m_OrganizerCore.doAfterLogin([this] () { this->checkModsForUpdates(); }); NexusInterface::instance(&m_PluginContainer)->getAccessManager()->apiCheck(apiKey); } else { @@ -4387,12 +4387,12 @@ void MainWindow::openIniFolder() void MainWindow::openDownloadsFolder() { - shell::ExploreFile(m_OrganizerCore.settings().getDownloadDirectory()); + shell::ExploreFile(m_OrganizerCore.settings().paths().downloads()); } void MainWindow::openModsFolder() { - shell::ExploreFile(m_OrganizerCore.settings().getModDirectory()); + shell::ExploreFile(m_OrganizerCore.settings().paths().mods()); } void MainWindow::openGameFolder() @@ -4758,7 +4758,7 @@ void MainWindow::on_modList_customContextMenuRequested(const QPoint &pos) menu.addSeparator(); - if (info->getNexusID() > 0 && Settings::instance().endorsementIntegration()) { + if (info->getNexusID() > 0 && Settings::instance().nexus().endorsementIntegration()) { switch (info->endorsedState()) { case ModInfo::ENDORSED_TRUE: { menu.addAction(tr("Un-Endorse"), this, SLOT(unendorse_clicked())); @@ -5007,19 +5007,19 @@ void MainWindow::on_actionSettings_triggered() { Settings &settings = m_OrganizerCore.settings(); - QString oldModDirectory(settings.getModDirectory()); - QString oldCacheDirectory(settings.getCacheDirectory()); - QString oldProfilesDirectory(settings.getProfileDirectory()); - QString oldManagedGameDirectory(settings.getManagedGameDirectory().value_or("")); - bool oldDisplayForeign(settings.displayForeign()); - bool proxy = settings.getUseProxy(); + QString oldModDirectory(settings.paths().mods()); + QString oldCacheDirectory(settings.paths().cache()); + QString oldProfilesDirectory(settings.paths().profiles()); + QString oldManagedGameDirectory(settings.game().directory().value_or("")); + bool oldDisplayForeign(settings.interface().displayForeign()); + bool proxy = settings.network().useProxy(); DownloadManager *dlManager = m_OrganizerCore.downloadManager(); SettingsDialog dialog(&m_PluginContainer, settings, this); dialog.exec(); - if (oldManagedGameDirectory != settings.getManagedGameDirectory()) { + if (oldManagedGameDirectory != settings.game().directory()) { QMessageBox::about(this, tr("Restarting MO"), tr("Changing the managed game directory requires restarting MO.\n" "Any pending downloads will be paused.\n\n" @@ -5029,28 +5029,28 @@ void MainWindow::on_actionSettings_triggered() } InstallationManager *instManager = m_OrganizerCore.installationManager(); - instManager->setModsDirectory(settings.getModDirectory()); - instManager->setDownloadDirectory(settings.getDownloadDirectory()); + instManager->setModsDirectory(settings.paths().mods()); + instManager->setDownloadDirectory(settings.paths().downloads()); fixCategories(); refreshFilters(); - if (settings.getProfileDirectory() != oldProfilesDirectory) { + if (settings.paths().profiles() != oldProfilesDirectory) { refreshProfiles(); } - if (dlManager->getOutputDirectory() != settings.getDownloadDirectory()) { + if (dlManager->getOutputDirectory() != settings.paths().downloads()) { if (dlManager->downloadsInProgress()) { MessageDialog::showMessage(tr("Can't change download directory while " "downloads are in progress!"), this); } else { - dlManager->setOutputDirectory(settings.getDownloadDirectory()); + dlManager->setOutputDirectory(settings.paths().downloads()); } } - if ((settings.getModDirectory() != oldModDirectory) - || (settings.displayForeign() != oldDisplayForeign)) { + if ((settings.paths().mods() != oldModDirectory) + || (settings.interface().displayForeign() != oldDisplayForeign)) { m_OrganizerCore.profileRefresh(); } @@ -5075,18 +5075,19 @@ void MainWindow::on_actionSettings_triggered() m_OrganizerCore.refreshLists(); } - if (settings.getCacheDirectory() != oldCacheDirectory) { - NexusInterface::instance(&m_PluginContainer)->setCacheDirectory(settings.getCacheDirectory()); + if (settings.paths().cache() != oldCacheDirectory) { + NexusInterface::instance(&m_PluginContainer)->setCacheDirectory( + settings.paths().cache()); } - if (proxy != settings.getUseProxy()) { - activateProxy(settings.getUseProxy()); + if (proxy != settings.network().useProxy()) { + activateProxy(settings.network().useProxy()); } ui->statusBar->checkSettings(m_OrganizerCore.settings()); updateDownloadView(); - m_OrganizerCore.setLogLevel(settings.logLevel()); + m_OrganizerCore.setLogLevel(settings.diagnostics().logLevel()); m_OrganizerCore.cycleDiagnostics(); toggleMO2EndorseState(); @@ -5402,10 +5403,10 @@ void MainWindow::motdReceived(const QString &motd) // internet connection is faster next time if (m_StartTime.secsTo(QTime::currentTime()) < 5) { uint hash = qHash(motd); - if (hash != m_OrganizerCore.settings().getMotDHash()) { + if (hash != m_OrganizerCore.settings().motdHash()) { MotDDialog dialog(motd); dialog.exec(); - m_OrganizerCore.settings().setMotDHash(hash); + m_OrganizerCore.settings().setMotdHash(hash); } } } @@ -5528,7 +5529,7 @@ void MainWindow::initDownloadView() void MainWindow::updateDownloadView() { // set the view attribute and default row sizes - if (m_OrganizerCore.settings().compactDownloads()) { + if (m_OrganizerCore.settings().interface().compactDownloads()) { ui->downloadView->setProperty("downloadView", "compact"); setStyleSheet("DownloadListWidget::item { padding: 4px 2px; }"); } else { @@ -5541,7 +5542,7 @@ void MainWindow::updateDownloadView() // reapply global stylesheet on the widget level (!) to override the defaults //ui->downloadView->setStyleSheet(styleSheet()); - ui->downloadView->setMetaDisplay(m_OrganizerCore.settings().metaDownloads()); + ui->downloadView->setMetaDisplay(m_OrganizerCore.settings().interface().metaDownloads()); ui->downloadView->style()->unpolish(ui->downloadView); ui->downloadView->style()->polish(ui->downloadView); qobject_cast<DownloadListHeader*>(ui->downloadView->header())->customResizeSections(); @@ -5554,7 +5555,7 @@ void MainWindow::modUpdateCheck(std::multimap<QString, int> IDs) ModInfo::manualUpdateCheck(&m_PluginContainer, this, IDs); } else { QString apiKey; - if (m_OrganizerCore.settings().getNexusApiKey(apiKey)) { + if (m_OrganizerCore.settings().nexus().apiKey(apiKey)) { m_OrganizerCore.doAfterLogin([=]() { this->modUpdateCheck(IDs); }); NexusInterface::instance(&m_PluginContainer)->getAccessManager()->apiCheck(apiKey); } else @@ -5566,7 +5567,7 @@ void MainWindow::toggleMO2EndorseState() { const auto& s = m_OrganizerCore.settings(); - if (!s.endorsementIntegration()) { + if (!s.nexus().endorsementIntegration()) { ui->actionEndorseMO->setVisible(false); return; } @@ -5576,7 +5577,7 @@ void MainWindow::toggleMO2EndorseState() bool enabled = false; QString text; - switch (s.endorsementState()) + switch (s.nexus().endorsementState()) { case EndorsementState::Accepted: { @@ -5631,9 +5632,9 @@ void MainWindow::nxmEndorsementsAvailable(QVariant userData, QVariant resultData mod->setIsEndorsed(false); } - if (Settings::instance().endorsementIntegration()) { + if (Settings::instance().nexus().endorsementIntegration()) { if (result->first == "skyrimspecialedition" && result->second.first == gamePlugin->nexusModOrganizerID()) { - m_OrganizerCore.settings().setEndorsementState( + m_OrganizerCore.settings().nexus().setEndorsementState( endorsementStateFromString(result->second.second)); toggleMO2EndorseState(); @@ -5642,13 +5643,13 @@ void MainWindow::nxmEndorsementsAvailable(QVariant userData, QVariant resultData } } - if (!searchedMO2NexusGame && Settings::instance().endorsementIntegration()) { + if (!searchedMO2NexusGame && Settings::instance().nexus().endorsementIntegration()) { auto gamePlugin = m_OrganizerCore.getGame("SkyrimSE"); if (gamePlugin) { auto iter = sorted.equal_range(gamePlugin->gameNexusName()); for (auto result = iter.first; result != iter.second; ++result) { if (result->second.first == gamePlugin->nexusModOrganizerID()) { - m_OrganizerCore.settings().setEndorsementState( + m_OrganizerCore.settings().nexus().setEndorsementState( endorsementStateFromString(result->second.second)); toggleMO2EndorseState(); @@ -5862,7 +5863,7 @@ void MainWindow::nxmEndorsementToggled(QString, int, QVariant, QVariant resultDa } } - m_OrganizerCore.settings().setEndorsementState(s); + m_OrganizerCore.settings().nexus().setEndorsementState(s); toggleMO2EndorseState(); if (!disconnect(sender(), SIGNAL(nxmEndorsementToggled(QString, int, QVariant, QVariant, int)), @@ -5901,7 +5902,7 @@ void MainWindow::nxmTrackedModsAvailable(QVariant userData, QVariant resultData, void MainWindow::nxmDownloadURLs(QString, int, int, QVariant, QVariant resultData, int) { - auto servers = m_OrganizerCore.settings().getServers(); + auto servers = m_OrganizerCore.settings().network().servers(); for (const QVariant &var : resultData.toList()) { const QVariantMap map = var.toMap(); @@ -5929,7 +5930,7 @@ void MainWindow::nxmDownloadURLs(QString, int, int, QVariant, QVariant resultDat } } - m_OrganizerCore.settings().updateServers(servers); + m_OrganizerCore.settings().network().updateServers(servers); } diff --git a/src/modinfodialog.cpp b/src/modinfodialog.cpp index f3840230..2178ef34 100644 --- a/src/modinfodialog.cpp +++ b/src/modinfodialog.cpp @@ -381,7 +381,7 @@ void ModInfoDialog::reAddTabs( Q_ASSERT(visibility.size() == m_tabs.size()); // ordered tab names from settings - const auto orderedNames = m_core->settings().geometry().getModInfoTabOrder(); + const auto orderedNames = m_core->settings().geometry().modInfoTabOrder(); // whether the tabs can be sorted; if the object name of a tab widget is not // found in orderedNames, the list cannot be sorted safely diff --git a/src/modinfodialogconflicts.cpp b/src/modinfodialogconflicts.cpp index 7840269d..3a71b405 100644 --- a/src/modinfodialogconflicts.cpp +++ b/src/modinfodialogconflicts.cpp @@ -409,7 +409,7 @@ void ConflictsTab::clear() void ConflictsTab::saveState(Settings& s) { - s.saveIndex(ui->tabConflictsTabs); + s.widgets().saveIndex(ui->tabConflictsTabs); m_general.saveState(s); m_advanced.saveState(s); @@ -417,7 +417,7 @@ void ConflictsTab::saveState(Settings& s) void ConflictsTab::restoreState(const Settings& s) { - s.restoreIndex(ui->tabConflictsTabs, 0); + s.widgets().restoreIndex(ui->tabConflictsTabs, 0); m_general.restoreState(s); m_advanced.restoreState(s); @@ -1014,17 +1014,17 @@ void AdvancedConflictsTab::clear() void AdvancedConflictsTab::saveState(Settings& s) { s.geometry().saveState(ui->conflictsAdvancedList->header()); - s.saveChecked(ui->conflictsAdvancedShowNoConflict); - s.saveChecked(ui->conflictsAdvancedShowAll); - s.saveChecked(ui->conflictsAdvancedShowNearest); + s.widgets().saveChecked(ui->conflictsAdvancedShowNoConflict); + s.widgets().saveChecked(ui->conflictsAdvancedShowAll); + s.widgets().saveChecked(ui->conflictsAdvancedShowNearest); } void AdvancedConflictsTab::restoreState(const Settings& s) { s.geometry().restoreState(ui->conflictsAdvancedList->header()); - s.restoreChecked(ui->conflictsAdvancedShowNoConflict); - s.restoreChecked(ui->conflictsAdvancedShowAll); - s.restoreChecked(ui->conflictsAdvancedShowNearest); + s.widgets().restoreChecked(ui->conflictsAdvancedShowNoConflict); + s.widgets().restoreChecked(ui->conflictsAdvancedShowAll); + s.widgets().restoreChecked(ui->conflictsAdvancedShowNearest); } void AdvancedConflictsTab::update() diff --git a/src/modinfodialogimages.cpp b/src/modinfodialogimages.cpp index 38c12d8a..9d347f57 100644 --- a/src/modinfodialogimages.cpp +++ b/src/modinfodialogimages.cpp @@ -130,13 +130,13 @@ void ImagesTab::update() void ImagesTab::saveState(Settings& s) { - s.saveChecked(ui->imagesShowDDS); + s.widgets().saveChecked(ui->imagesShowDDS); s.geometry().saveState(ui->tabImagesSplitter); } void ImagesTab::restoreState(const Settings& s) { - s.restoreChecked(ui->imagesShowDDS); + s.widgets().restoreChecked(ui->imagesShowDDS); s.geometry().restoreState(ui->tabImagesSplitter); } diff --git a/src/modinfodialognexus.cpp b/src/modinfodialognexus.cpp index 6d28cbe3..95e62328 100644 --- a/src/modinfodialognexus.cpp +++ b/src/modinfodialognexus.cpp @@ -19,7 +19,7 @@ NexusTab::NexusTab(ModInfoDialogTabContext cx) : ModInfoDialogTab(std::move(cx)), m_requestStarted(false), m_loading(false) { ui->modID->setValidator(new QIntValidator(ui->modID)); - ui->endorse->setVisible(core().settings().endorsementIntegration()); + ui->endorse->setVisible(core().settings().nexus().endorsementIntegration()); connect(ui->modID, &QLineEdit::editingFinished, [&]{ onModIDChanged(); }); connect( diff --git a/src/modinfooverwrite.cpp b/src/modinfooverwrite.cpp index 37c8c650..fb110abb 100644 --- a/src/modinfooverwrite.cpp +++ b/src/modinfooverwrite.cpp @@ -23,7 +23,7 @@ bool ModInfoOverwrite::isEmpty() const QString ModInfoOverwrite::absolutePath() const { - return Settings::instance().getOverwriteDirectory(); + return Settings::instance().paths().overwrite(); } std::vector<ModInfo::EFlag> ModInfoOverwrite::getFlags() const diff --git a/src/modinforegular.cpp b/src/modinforegular.cpp index ce29e11e..3cff914a 100644 --- a/src/modinforegular.cpp +++ b/src/modinforegular.cpp @@ -631,7 +631,7 @@ std::vector<ModInfo::EFlag> ModInfoRegular::getFlags() const std::vector<ModInfo::EFlag> result = ModInfoWithConflictInfo::getFlags(); if ((m_NexusID > 0) && (endorsedState() == ENDORSED_FALSE) && - Settings::instance().endorsementIntegration()) { + Settings::instance().nexus().endorsementIntegration()) { result.push_back(ModInfo::FLAG_NOTENDORSED); } if ((m_NexusID > 0) && diff --git a/src/modlist.cpp b/src/modlist.cpp index 94b4a387..6018d3d4 100644 --- a/src/modlist.cpp +++ b/src/modlist.cpp @@ -390,7 +390,7 @@ QVariant ModList::data(const QModelIndex &modelIndex, int role) const return QVariant(); } else if (role == Qt::ForegroundRole) { if (modInfo->hasFlag(ModInfo::FLAG_SEPARATOR) && modInfo->getColor().isValid()) { - return Settings::getIdealTextColor(modInfo->getColor()); + return ColorSettings::idealTextColor(modInfo->getColor()); } else if (column == COL_NAME) { int highlight = modInfo->getHighlight(); if (highlight & ModInfo::HIGHLIGHT_IMPORTANT) @@ -428,7 +428,7 @@ QVariant ModList::data(const QModelIndex &modelIndex, int role) const } else if (modInfo->hasFlag(ModInfo::FLAG_SEPARATOR) && modInfo->getColor().isValid() && ((role != ViewMarkingScrollBar::DEFAULT_ROLE) - || Settings::instance().colorSeparatorScrollbar())) { + || Settings::instance().colors().colorSeparatorScrollbar())) { return modInfo->getColor(); } else { return QVariant(); @@ -999,8 +999,8 @@ bool ModList::dropURLs(const QMimeData *mimeData, int row, const QModelIndex &pa ModInfo::Ptr modInfo = ModInfo::getByIndex(row); QDir modDir = QDir(modInfo->absolutePath()); - QDir allModsDir(Settings::instance().getModDirectory()); - QDir overwriteDir(Settings::instance().getOverwriteDirectory()); + QDir allModsDir(Settings::instance().paths().mods()); + QDir overwriteDir(Settings::instance().paths().overwrite()); QStringList sourceList; QStringList targetList; diff --git a/src/nxmaccessmanager.cpp b/src/nxmaccessmanager.cpp index 16190ca4..c6ef7bc7 100644 --- a/src/nxmaccessmanager.cpp +++ b/src/nxmaccessmanager.cpp @@ -572,7 +572,7 @@ NXMAccessManager::NXMAccessManager(QObject *parent, const QString &moVersion) m_validator.finished = [&](auto&& user){ onValidatorFinished(user); }; setCookieJar(new PersistentCookieJar(QDir::fromNativeSeparators( - Settings::instance().getCacheDirectory() + "/nexus_cookies.dat"))); + Settings::instance().paths().cache() + "/nexus_cookies.dat"))); if (networkAccessible() == QNetworkAccessManager::UnknownAccessibility) { // why is this necessary all of a sudden? diff --git a/src/organizercore.cpp b/src/organizercore.cpp index af0cf969..1a89641d 100644 --- a/src/organizercore.cpp +++ b/src/organizercore.cpp @@ -146,7 +146,7 @@ static void startSteam(QWidget *widget) QStringList args; QString username; QString password; - if (Settings::instance().getSteamLogin(username, password)) { + if (Settings::instance().steam().login(username, password)) { args << "-login"; args << username; if (password != "") { @@ -275,12 +275,13 @@ OrganizerCore::OrganizerCore(Settings &settings) , m_ArchivesInit(false) , m_PluginListsWriter(std::bind(&OrganizerCore::savePluginList, this)) { - m_DownloadManager.setOutputDirectory(m_Settings.getDownloadDirectory()); + m_DownloadManager.setOutputDirectory(m_Settings.paths().downloads()); - NexusInterface::instance(m_PluginContainer)->setCacheDirectory(m_Settings.getCacheDirectory()); + NexusInterface::instance(m_PluginContainer)->setCacheDirectory( + m_Settings.paths().cache()); - m_InstallationManager.setModsDirectory(m_Settings.getModDirectory()); - m_InstallationManager.setDownloadDirectory(m_Settings.getDownloadDirectory()); + m_InstallationManager.setModsDirectory(m_Settings.paths().mods()); + m_InstallationManager.setDownloadDirectory(m_Settings.paths().downloads()); connect(&m_DownloadManager, SIGNAL(downloadSpeed(QString, int)), this, SLOT(downloadSpeed(QString, int))); @@ -333,7 +334,7 @@ OrganizerCore::~OrganizerCore() void OrganizerCore::storeSettings() { if (m_CurrentProfile != nullptr) { - m_Settings.setSelectedProfileName(m_CurrentProfile->name()); + m_Settings.game().setSelectedProfileName(m_CurrentProfile->name()); } m_ExecutablesList.store(m_Settings); @@ -356,7 +357,7 @@ void OrganizerCore::storeSettings() QMessageBox::critical( qApp->activeWindow(), tr("Failed to write settings"), tr("An error occurred trying to write back MO settings to %1: %2") - .arg(m_Settings.getFilename(), reason)); + .arg(m_Settings.filename(), reason)); } } @@ -432,8 +433,9 @@ void OrganizerCore::updateExecutablesList() // TODO this has nothing to do with executables list move to an appropriate // function! - ModInfo::updateFromDisc(m_Settings.getModDirectory(), &m_DirectoryStructure, - m_PluginContainer, m_Settings.displayForeign(), managedGame()); + ModInfo::updateFromDisc( + m_Settings.paths().mods(), &m_DirectoryStructure, + m_PluginContainer, m_Settings.interface().displayForeign(), managedGame()); } void OrganizerCore::setUserInterface(IUserInterface *userInterface, @@ -478,7 +480,7 @@ void OrganizerCore::setUserInterface(IUserInterface *userInterface, if (userInterface != nullptr) { // this currently wouldn't work reliably if the ui isn't initialized yet to // display the result - if (isOnline() && !m_Settings.offlineMode()) { + if (isOnline() && !m_Settings.network().offlineMode()) { m_Updater.testForUpdate(); } else { log::debug("user doesn't seem to be connected to the internet"); @@ -541,7 +543,7 @@ bool OrganizerCore::nexusApi(bool retry) return false; } else { QString apiKey; - if (m_Settings.getNexusApiKey(apiKey)) { + if (m_Settings.nexus().apiKey(apiKey)) { // credentials stored or user entered them manually log::debug("attempt to verify nexus api key"); accessManager->apiCheck(apiKey); @@ -608,7 +610,7 @@ void OrganizerCore::removeOrigin(const QString &name) void OrganizerCore::downloadSpeed(const QString &serverName, int bytesPerSecond) { - m_Settings.setDownloadSpeed(serverName, bytesPerSecond); + m_Settings.network().setDownloadSpeed(serverName, bytesPerSecond); } InstallationManager *OrganizerCore::installationManager() @@ -629,9 +631,9 @@ bool OrganizerCore::createDirectory(const QString &path) { } bool OrganizerCore::checkPathSymlinks() { - bool hasSymlink = (QFileInfo(m_Settings.getProfileDirectory()).isSymLink() || - QFileInfo(m_Settings.getModDirectory()).isSymLink() || - QFileInfo(m_Settings.getOverwriteDirectory()).isSymLink()); + bool hasSymlink = (QFileInfo(m_Settings.paths().profiles()).isSymLink() || + QFileInfo(m_Settings.paths().mods()).isSymLink() || + QFileInfo(m_Settings.paths().overwrite()).isSymLink()); if (hasSymlink) { QMessageBox::critical(nullptr, QObject::tr("Error"), QObject::tr("One of the configured MO2 directories (profiles, mods, or overwrite) " @@ -643,17 +645,17 @@ bool OrganizerCore::checkPathSymlinks() { } bool OrganizerCore::bootstrap() { - return createDirectory(m_Settings.getProfileDirectory()) && - createDirectory(m_Settings.getModDirectory()) && - createDirectory(m_Settings.getDownloadDirectory()) && - createDirectory(m_Settings.getOverwriteDirectory()) && + return createDirectory(m_Settings.paths().profiles()) && + createDirectory(m_Settings.paths().mods()) && + createDirectory(m_Settings.paths().downloads()) && + createDirectory(m_Settings.paths().overwrite()) && createDirectory(QString::fromStdWString(crashDumpsPath())) && checkPathSymlinks() && cycleDiagnostics(); } void OrganizerCore::createDefaultProfile() { - QString profilesPath = settings().getProfileDirectory(); + QString profilesPath = settings().paths().profiles(); if (QDir(profilesPath).entryList(QDir::AllDirs | QDir::NoDotAndDotDot).size() == 0) { Profile newProf("Default", managedGame(), false); @@ -674,18 +676,18 @@ void OrganizerCore::updateVFSParams( void OrganizerCore::setLogLevel(log::Levels level) { - m_Settings.setLogLevel(level); + m_Settings.diagnostics().setLogLevel(level); updateVFSParams( - m_Settings.logLevel(), - m_Settings.crashDumpsType(), + m_Settings.diagnostics().logLevel(), + m_Settings.diagnostics().crashDumpsType(), m_Settings.executablesBlacklist()); - log::getDefault().setLevel(m_Settings.logLevel()); + log::getDefault().setLevel(m_Settings.diagnostics().logLevel()); } bool OrganizerCore::cycleDiagnostics() { - if (int maxDumps = settings().crashDumpsMax()) + if (int maxDumps = settings().diagnostics().crashDumpsMax()) removeOldFiles(QString::fromStdWString(crashDumpsPath()), "*.dmp", maxDumps, QDir::Time|QDir::Reversed); return true; } @@ -720,7 +722,7 @@ void OrganizerCore::setCurrentProfile(const QString &profileName) return; } - QDir profileBaseDir(settings().getProfileDirectory()); + QDir profileBaseDir(settings().paths().profiles()); QString profileDir = profileBaseDir.absoluteFilePath(profileName); if (!QDir(profileDir).exists()) { @@ -744,7 +746,7 @@ void OrganizerCore::setCurrentProfile(const QString &profileName) m_CurrentProfile->deactivateInvalidation(); } - m_Settings.setSelectedProfileName(m_CurrentProfile->name()); + m_Settings.game().setSelectedProfileName(m_CurrentProfile->name()); connect(m_CurrentProfile, SIGNAL(modStatusChanged(uint)), this, SLOT(modStatusChanged(uint))); connect(m_CurrentProfile, SIGNAL(modStatusChanged(QList<uint>)), this, SLOT(modStatusChanged(QList<uint>))); @@ -776,22 +778,22 @@ QString OrganizerCore::profilePath() const QString OrganizerCore::downloadsPath() const { - return QDir::fromNativeSeparators(m_Settings.getDownloadDirectory()); + return QDir::fromNativeSeparators(m_Settings.paths().downloads()); } QString OrganizerCore::overwritePath() const { - return QDir::fromNativeSeparators(m_Settings.getOverwriteDirectory()); + return QDir::fromNativeSeparators(m_Settings.paths().overwrite()); } QString OrganizerCore::basePath() const { - return QDir::fromNativeSeparators(m_Settings.getBaseDirectory()); + return QDir::fromNativeSeparators(m_Settings.paths().base()); } QString OrganizerCore::modsPath() const { - return QDir::fromNativeSeparators(m_Settings.getModDirectory()); + return QDir::fromNativeSeparators(m_Settings.paths().mods()); } MOBase::VersionInfo OrganizerCore::appVersion() const @@ -821,10 +823,10 @@ MOBase::IModInterface *OrganizerCore::createMod(GuessedValue<QString> &name) return nullptr; } - m_InstallationManager.setModsDirectory(m_Settings.getModDirectory()); + m_InstallationManager.setModsDirectory(m_Settings.paths().mods()); QString targetDirectory - = QDir::fromNativeSeparators(m_Settings.getModDirectory()) + = QDir::fromNativeSeparators(m_Settings.paths().mods()) .append("/") .append(name); @@ -912,7 +914,7 @@ MOBase::IModInterface *OrganizerCore::installMod(const QString &fileName, modName.update(initModName, GUESS_USER); } m_CurrentProfile->writeModlistNow(); - m_InstallationManager.setModsDirectory(m_Settings.getModDirectory()); + m_InstallationManager.setModsDirectory(m_Settings.paths().mods()); if (m_InstallationManager.install(fileName, modName, hasIniTweaks)) { MessageDialog::showMessage(tr("Installation successful"), qApp->activeWindow()); @@ -977,7 +979,7 @@ void OrganizerCore::installDownload(int index) m_CurrentProfile->writeModlistNow(); bool hasIniTweaks = false; - m_InstallationManager.setModsDirectory(m_Settings.getModDirectory()); + m_InstallationManager.setModsDirectory(m_Settings.paths().mods()); if (m_InstallationManager.install(fileName, modName, hasIniTweaks)) { MessageDialog::showMessage(tr("Installation successful"), qApp->activeWindow()); @@ -1270,7 +1272,7 @@ bool OrganizerCore::previewFileWithAlternatives( else { // crude: we search for the next slash after the base mod directory to skip // everything up to the data-relative directory - int offset = settings().getModDirectory().size() + 1; + int offset = settings().paths().mods().size() + 1; offset = fileName.indexOf("/", offset); fileName = fileName.mid(offset + 1); } @@ -1412,7 +1414,7 @@ HANDLE OrganizerCore::spawnBinaryDirect(const QFileInfo &binary, LPDWORD exitCode) { HANDLE processHandle = spawnBinaryProcess(binary, arguments, profileName, currentDirectory, steamAppID, customOverwrite, forcedLibraries); - if (Settings::instance().lockGUI() && processHandle != INVALID_HANDLE_VALUE) { + if (Settings::instance().interface().lockGUI() && processHandle != INVALID_HANDLE_VALUE) { std::unique_ptr<LockedDialog> dlg; ILockedWaitingForProcess* uilock = nullptr; @@ -1461,7 +1463,7 @@ HANDLE OrganizerCore::spawnBinaryProcess(const QFileInfo &binary, ::SetEnvironmentVariableW(L"SteamAPPId", ToWString(steamAppID).c_str()); } else { ::SetEnvironmentVariableW(L"SteamAPPId", - ToWString(m_Settings.getSteamAppID()).c_str()); + ToWString(m_Settings.steam().appID()).c_str()); } QWidget *window = qApp->activeWindow(); @@ -1477,7 +1479,7 @@ HANDLE OrganizerCore::spawnBinaryProcess(const QFileInfo &binary, || QFileInfo(managedGame()->gameDirectory().absoluteFilePath( "steam_api64.dll")) .exists()) - && (m_Settings.getLoadMechanism() == LoadMechanism::LOAD_MODORGANIZER)) { + && (m_Settings.game().loadMechanismType() == LoadMechanism::LOAD_MODORGANIZER)) { bool steamFound = true; bool steamAccess = true; @@ -1592,7 +1594,7 @@ HANDLE OrganizerCore::spawnBinaryProcess(const QFileInfo &binary, } } - QString modsPath = settings().getModDirectory(); + QString modsPath = settings().paths().mods(); // Check if this a request with either an executable or a working directory under our mods folder // then will start the process in a virtualized "environment" with the appropriate paths fixed: @@ -1749,7 +1751,7 @@ HANDLE OrganizerCore::startApplication(const QString &executable, bool OrganizerCore::waitForApplication(HANDLE handle, LPDWORD exitCode) { - if (!Settings::instance().lockGUI()) + if (!Settings::instance().interface().lockGUI()) return true; ILockedWaitingForProcess* uilock = nullptr; @@ -1960,8 +1962,10 @@ void OrganizerCore::refreshModList(bool saveChanges) if (saveChanges) { m_CurrentProfile->writeModlistNow(true); } - ModInfo::updateFromDisc(m_Settings.getModDirectory(), &m_DirectoryStructure, - m_PluginContainer, m_Settings.displayForeign(), managedGame()); + + ModInfo::updateFromDisc( + m_Settings.paths().mods(), &m_DirectoryStructure, + m_PluginContainer, m_Settings.interface().displayForeign(), managedGame()); m_CurrentProfile->refreshModStatus(); @@ -2130,7 +2134,7 @@ void OrganizerCore::updateModsInDirectoryStructure(QMap<unsigned int, ModInfo::P updateModsActiveState(modInfo.keys(), true); m_PluginList.blockSignals(false); // now we need to refresh the bsa list and save it so there is no confusion - // about what archives are avaiable and active + // about what archives are available and active refreshBSAList(); if (m_UserInterface != nullptr) { m_UserInterface->archivesWriter().writeImmediately(false); @@ -2156,7 +2160,7 @@ void OrganizerCore::loggedInAction(QWidget* parent, std::function<void ()> f) f(); } else { QString apiKey; - if (settings().getNexusApiKey(apiKey)) { + if (settings().nexus().apiKey(apiKey)) { doAfterLogin([f]{ f(); }); NexusInterface::instance(m_PluginContainer)->getAccessManager()->apiCheck(apiKey); } else { @@ -2295,8 +2299,10 @@ void OrganizerCore::profileRefresh() { // have to refresh mods twice (again in refreshModList), otherwise the refresh // isn't complete. Not sure why - ModInfo::updateFromDisc(m_Settings.getModDirectory(), &m_DirectoryStructure, - m_PluginContainer, m_Settings.displayForeign(), managedGame()); + ModInfo::updateFromDisc( + m_Settings.paths().mods(), &m_DirectoryStructure, + m_PluginContainer, m_Settings.interface().displayForeign(), managedGame()); + m_CurrentProfile->refreshModStatus(); refreshModList(); @@ -2463,7 +2469,7 @@ void OrganizerCore::syncOverwrite() SyncOverwriteDialog syncDialog(modInfo->absolutePath(), m_DirectoryStructure, qApp->activeWindow()); if (syncDialog.exec() == QDialog::Accepted) { - syncDialog.apply(QDir::fromNativeSeparators(m_Settings.getModDirectory())); + syncDialog.apply(QDir::fromNativeSeparators(m_Settings.paths().mods())); modInfo->testValid(); refreshDirectoryStructure(); } @@ -2486,7 +2492,7 @@ std::vector<unsigned int> OrganizerCore::activeProblems() const const auto& hookdll = oldMO1HookDll(); if (!hookdll.isEmpty()) { // This warning will now be shown every time the problems are checked, which is a bit - // of a "log spam". But since this is a sevre error which will most likely make the + // of a "log spam". But since this is a sever error which will most likely make the // game crash/freeze/etc. and is very hard to diagnose, this "log spam" will make it // easier for the user to notice the warning. log::warn("hook.dll found in game folder: {}", hookdll); @@ -2562,7 +2568,7 @@ void OrganizerCore::savePluginList() } m_PluginList.saveTo(m_CurrentProfile->getLockedOrderFileName(), m_CurrentProfile->getDeleterFileName(), - m_Settings.hideUncheckedPlugins()); + m_Settings.game().hideUncheckedPlugins()); m_PluginList.saveLoadOrder(*m_DirectoryStructure); } @@ -2574,7 +2580,7 @@ void OrganizerCore::prepareStart() m_CurrentProfile->writeModlist(); m_CurrentProfile->createTweakedIniFile(); saveCurrentLists(); - m_Settings.setupLoadMechanism(); + m_Settings.game().setupLoadMechanism(); storeSettings(); } @@ -2588,7 +2594,7 @@ std::vector<Mapping> OrganizerCore::fileMapping(const QString &profileName, } IPluginGame *game = qApp->property("managed_game").value<IPluginGame *>(); - Profile profile(QDir(m_Settings.getProfileDirectory() + "/" + profileName), + Profile profile(QDir(m_Settings.paths().profiles() + "/" + profileName), game); MappingType result; @@ -2634,7 +2640,7 @@ std::vector<Mapping> OrganizerCore::fileMapping(const QString &profileName, } result.insert(result.end(), { - QDir::toNativeSeparators(m_Settings.getOverwriteDirectory()), + QDir::toNativeSeparators(m_Settings.paths().overwrite()), dataPath, true, customOverwrite.isEmpty() diff --git a/src/pluginlist.cpp b/src/pluginlist.cpp index ddfe492e..33423225 100644 --- a/src/pluginlist.cpp +++ b/src/pluginlist.cpp @@ -191,7 +191,7 @@ void PluginList::refresh(const QString &profileName continue;
}
- bool forceEnabled = Settings::instance().forceEnableCoreFiles() &&
+ bool forceEnabled = Settings::instance().game().forceEnableCoreFiles() &&
primaryPlugins.contains(filename, Qt::CaseInsensitive);
//(std::find(primaryPlugins.begin(), primaryPlugins.end(), filename.toLower()) != primaryPlugins.end());
diff --git a/src/profile.cpp b/src/profile.cpp index 7f4ebcaa..e76060b9 100644 --- a/src/profile.cpp +++ b/src/profile.cpp @@ -73,7 +73,7 @@ Profile::Profile(const QString &name, IPluginGame const *gamePlugin, bool useDef : m_ModListWriter(std::bind(&Profile::doWriteModlist, this)) , m_GamePlugin(gamePlugin) { - QString profilesDir = Settings::instance().getProfileDirectory(); + QString profilesDir = Settings::instance().paths().profiles(); QDir profileBase(profilesDir); QString fixedName = name; if (!fixDirectoryName(fixedName)) { @@ -299,7 +299,7 @@ void Profile::createTweakedIniFile() // static void Profile::renameModInAllProfiles(const QString& oldName, const QString& newName) { - QDir profilesDir(Settings::instance().getProfileDirectory()); + QDir profilesDir(Settings::instance().paths().profiles()); profilesDir.setFilter(QDir::AllDirs | QDir::NoDotAndDotDot); QDirIterator profileIter(profilesDir); while (profileIter.hasNext()) { @@ -655,7 +655,7 @@ void Profile::setModPriority(unsigned int index, int &newPriority) Profile *Profile::createPtrFrom(const QString &name, const Profile &reference, MOBase::IPluginGame const *gamePlugin) { - QString profileDirectory = Settings::instance().getProfileDirectory() + "/" + name; + QString profileDirectory = Settings::instance().paths().profiles() + "/" + name; reference.copyFilesTo(profileDirectory); return new Profile(QDir(profileDirectory), gamePlugin); } @@ -906,7 +906,7 @@ QString Profile::savePath() const void Profile::rename(const QString &newName) { - QDir profileDir(Settings::instance().getProfileDirectory()); + QDir profileDir(Settings::instance().paths().profiles()); profileDir.rename(name(), newName); m_Directory.setPath(profileDir.absoluteFilePath(newName)); } diff --git a/src/profilesdialog.cpp b/src/profilesdialog.cpp index 2f1bd059..c91f48f4 100644 --- a/src/profilesdialog.cpp +++ b/src/profilesdialog.cpp @@ -57,7 +57,7 @@ ProfilesDialog::ProfilesDialog(const QString &profileName, MOBase::IPluginGame c {
ui->setupUi(this);
- QDir profilesDir(Settings::instance().getProfileDirectory());
+ QDir profilesDir(Settings::instance().paths().profiles());
profilesDir.setFilter(QDir::AllDirs | QDir::NoDotAndDotDot);
QDirIterator profileIter(profilesDir);
@@ -203,7 +203,7 @@ void ProfilesDialog::on_removeProfileButton_clicked() if (confirmBox.exec() == QMessageBox::Yes) {
QString profilePath;
if (profileToDelete.get() == nullptr) {
- profilePath = Settings::instance().getProfileDirectory()
+ profilePath = Settings::instance().paths().profiles()
+ "/" + ui->profilesList->currentItem()->text();
if (QMessageBox::question(this, tr("Profile broken"),
tr("This profile you're about to delete seems to be broken or the path is invalid. "
diff --git a/src/settings.cpp b/src/settings.cpp index 71288950..8b063efb 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -150,7 +150,7 @@ std::optional<T> getOptional( template <class T> T get( const QSettings& settings, - const QString& section, const QString& key, T def={}) + const QString& section, const QString& key, T def) { if (auto v=getOptional<T>(settings, section, key)) { return *v; @@ -453,115 +453,7 @@ void warnIfNotCheckable(const QAbstractButton* b) } -Settings *Settings::s_Instance = nullptr; - -Settings::Settings(const QString& path) : - m_Settings(path, QSettings::IniFormat), - m_Geometry(m_Settings), m_Colors(m_Settings), m_Plugins(m_Settings) -{ - if (s_Instance != nullptr) { - throw std::runtime_error("second instance of \"Settings\" created"); - } else { - s_Instance = this; - } - - MOBase::QuestionBoxMemory::setCallbacks( - [this](auto&& w, auto&& f){ return getQuestionButton(w, f); }, - [this](auto&& w, auto&& b){ setQuestionWindowButton(w, b); }, - [this](auto&& w, auto&& f, auto&& b){ setQuestionFileButton(w, f, b); }); -} - -Settings::~Settings() -{ - MOBase::QuestionBoxMemory::setCallbacks({}, {}, {}); - s_Instance = nullptr; -} - -Settings &Settings::instance() -{ - if (s_Instance == nullptr) { - throw std::runtime_error("no instance of \"Settings\""); - } - return *s_Instance; -} - -void Settings::processUpdates( - const QVersionNumber& currentVersion, const QVersionNumber& lastVersion) -{ - if (getFirstStart()) { - return; - } - - if (lastVersion < QVersionNumber(2, 2, 0)) { - remove(m_Settings, "Settings", "steam_password"); - remove(m_Settings, "Settings", "nexus_username"); - remove(m_Settings, "Settings", "nexus_password"); - remove(m_Settings, "Settings", "nexus_login"); - remove(m_Settings, "Settings", "nexus_api_key"); - remove(m_Settings, "Settings", "ask_for_nexuspw"); - remove(m_Settings, "Settings", "nmm_version"); - - removeSection(m_Settings, "Servers"); - } - - if (lastVersion < QVersionNumber(2, 2, 1)) { - remove(m_Settings, "General", "mod_info_tabs"); - remove(m_Settings, "General", "mod_info_conflict_expanders"); - remove(m_Settings, "General", "mod_info_conflicts"); - remove(m_Settings, "General", "mod_info_advanced_conflicts"); - remove(m_Settings, "General", "mod_info_conflicts_overwrite"); - remove(m_Settings, "General", "mod_info_conflicts_noconflict"); - remove(m_Settings, "General", "mod_info_conflicts_overwritten"); - } - - if (lastVersion < QVersionNumber(2, 2, 2)) { - // log splitter is gone, it's a dock now - remove(m_Settings, "General", "log_split"); - } - - //save version in all case - set(m_Settings, "General", "version", currentVersion.toString()); -} - -QString Settings::getFilename() const -{ - return m_Settings.fileName(); -} - -void Settings::registerAsNXMHandler(bool force) -{ - const auto nxmPath = QCoreApplication::applicationDirPath() + "/nxmhandler.exe"; - const auto executable = QCoreApplication::applicationFilePath(); - - QString mode = force ? "forcereg" : "reg"; - QString parameters = mode + " " + m_GamePlugin->gameShortName(); - for (const QString& altGame : m_GamePlugin->validShortNames()) { - parameters += "," + altGame; - } - parameters += " \"" + executable + "\""; - - if (!shell::Execute(nxmPath, parameters)) { - QMessageBox::critical( - nullptr, tr("Failed"), tr("Failed to start the helper application")); - } -} - -bool Settings::colorSeparatorScrollbar() const -{ - return get<bool>(m_Settings, "Settings", "colorSeparatorScrollbars", true); -} - -void Settings::setColorSeparatorScrollbar(bool b) -{ - set(m_Settings, "Settings", "colorSeparatorScrollbars", b); -} - -void Settings::managedGameChanged(IPluginGame const *gamePlugin) -{ - m_GamePlugin = gamePlugin; -} - -bool Settings::obfuscate(const QString key, const QString data) +bool setWindowsCredential(const QString key, const QString data) { QString finalKey("ModOrganizer2_" + key); wchar_t* keyData = new wchar_t[finalKey.size()+1]; @@ -592,7 +484,7 @@ bool Settings::obfuscate(const QString key, const QString data) return result; } -QString Settings::deObfuscate(const QString key) +QString getWindowsCredential(const QString key) { QString result; QString finalKey("ModOrganizer2_" + key); @@ -614,248 +506,91 @@ QString Settings::deObfuscate(const QString key) return result; } -QColor Settings::getIdealTextColor(const QColor& rBackgroundColor) -{ - if (rBackgroundColor.alpha() == 0) - return QColor(Qt::black); - - const int THRESHOLD = 106 * 255.0f / rBackgroundColor.alpha(); - int BackgroundDelta = (rBackgroundColor.red() * 0.299) + (rBackgroundColor.green() * 0.587) + (rBackgroundColor.blue() * 0.114); - return QColor((255 - BackgroundDelta <= THRESHOLD) ? Qt::black : Qt::white); -} - - -bool Settings::hideUncheckedPlugins() const -{ - return get<bool>(m_Settings, "Settings", "hide_unchecked_plugins", false); -} - -void Settings::setHideUncheckedPlugins(bool b) -{ - set(m_Settings, "Settings", "hide_unchecked_plugins", b); -} - -bool Settings::forceEnableCoreFiles() const -{ - return get<bool>(m_Settings, "Settings", "force_enable_core_files", true); -} - -void Settings::setForceEnableCoreFiles(bool b) -{ - set(m_Settings, "Settings", "force_enable_core_files", b); -} - -bool Settings::lockGUI() const -{ - return get<bool>(m_Settings, "Settings", "lock_gui", true); -} - -void Settings::setLockGUI(bool b) -{ - set(m_Settings, "Settings", "lock_gui", b); -} - -bool Settings::automaticLoginEnabled() const -{ - return get<bool>(m_Settings, "Settings", "nexus_login", false); -} -QString Settings::getSteamAppID() const -{ - return get<QString>(m_Settings, "Settings", "app_id", m_GamePlugin->steamAPPId()); -} +Settings *Settings::s_Instance = nullptr; -void Settings::setSteamAppID(const QString& id) +Settings::Settings(const QString& path) : + m_Settings(path, QSettings::IniFormat), + m_Game(m_Settings), m_Geometry(m_Settings), m_Widgets(m_Settings), + m_Colors(m_Settings), m_Plugins(m_Settings), m_Paths(m_Settings), + m_Network(m_Settings), m_Nexus(*this, m_Settings), m_Steam(*this, m_Settings), + m_Interface(m_Settings), m_Diagnostics(m_Settings) { - if (id.isEmpty()) { - remove(m_Settings, "Settings", "app_id"); + if (s_Instance != nullptr) { + throw std::runtime_error("second instance of \"Settings\" created"); } else { - set(m_Settings, "Settings", "app_id", id); + s_Instance = this; } } -bool Settings::usePrereleases() const -{ - return get<bool>(m_Settings, "Settings", "use_prereleases", false); -} - -void Settings::setUsePrereleases(bool b) +Settings::~Settings() { - set(m_Settings, "Settings", "use_prereleases", b); + MOBase::QuestionBoxMemory::setCallbacks({}, {}, {}); + s_Instance = nullptr; } -QString Settings::getConfigurablePath(const QString &key, - const QString &def, - bool resolve) const +Settings &Settings::instance() { - QString result = QDir::fromNativeSeparators( - get<QString>(m_Settings, "Settings", key, QString("%BASE_DIR%/") + def)); - - if (resolve) { - result.replace("%BASE_DIR%", getBaseDirectory()); + if (s_Instance == nullptr) { + throw std::runtime_error("no instance of \"Settings\""); } - - return result; + return *s_Instance; } -void Settings::setConfigurablePath(const QString &key, const QString& path) +void Settings::processUpdates( + const QVersionNumber& currentVersion, const QVersionNumber& lastVersion) { - if (path.isEmpty()) { - remove(m_Settings, "Settings", key); - } else { - set(m_Settings, "Settings", key, path); + if (firstStart()) { + return; } -} -QString Settings::getBaseDirectory() const -{ - return QDir::fromNativeSeparators(get<QString>(m_Settings, - "Settings", "base_directory", qApp->property("dataPath").toString())); -} - -QString Settings::getDownloadDirectory(bool resolve) const -{ - return getConfigurablePath( - "download_directory", - ToQString(AppConfig::downloadPath()), - resolve); -} - -QString Settings::getCacheDirectory(bool resolve) const -{ - return getConfigurablePath( - "cache_directory", - ToQString(AppConfig::cachePath()), - resolve); -} - -QString Settings::getModDirectory(bool resolve) const -{ - return getConfigurablePath( - "mod_directory", - ToQString(AppConfig::modsPath()), - resolve); -} - -QString Settings::getProfileDirectory(bool resolve) const -{ - return getConfigurablePath( - "profiles_directory", - ToQString(AppConfig::profilesPath()), - resolve); -} - -QString Settings::getOverwriteDirectory(bool resolve) const -{ - return getConfigurablePath( - "overwrite_directory", - ToQString(AppConfig::overwritePath()), - resolve); -} + if (lastVersion < QVersionNumber(2, 2, 0)) { + remove(m_Settings, "Settings", "steam_password"); + remove(m_Settings, "Settings", "nexus_username"); + remove(m_Settings, "Settings", "nexus_password"); + remove(m_Settings, "Settings", "nexus_login"); + remove(m_Settings, "Settings", "nexus_api_key"); + remove(m_Settings, "Settings", "ask_for_nexuspw"); + remove(m_Settings, "Settings", "nmm_version"); -void Settings::setBaseDirectory(const QString& path) -{ - if (path.isEmpty()) { - remove(m_Settings, "Settings", "base_directory"); - } else { - set(m_Settings, "Settings", "base_directory", path); + removeSection(m_Settings, "Servers"); } -} - -void Settings::setDownloadDirectory(const QString& path) -{ - setConfigurablePath("download_directory", path); -} -void Settings::setModDirectory(const QString& path) -{ - setConfigurablePath("mod_directory", path); -} - -void Settings::setCacheDirectory(const QString& path) -{ - setConfigurablePath("cache_directory", path); -} - -void Settings::setProfileDirectory(const QString& path) -{ - setConfigurablePath("profiles_directory", path); -} - -void Settings::setOverwriteDirectory(const QString& path) -{ - setConfigurablePath("overwrite_directory", path); -} - -std::optional<QString> Settings::getManagedGameDirectory() const -{ - if (auto v=getOptional<QByteArray>(m_Settings, "General", "gamePath")) { - return QString::fromUtf8(*v); + if (lastVersion < QVersionNumber(2, 2, 1)) { + remove(m_Settings, "General", "mod_info_tabs"); + remove(m_Settings, "General", "mod_info_conflict_expanders"); + remove(m_Settings, "General", "mod_info_conflicts"); + remove(m_Settings, "General", "mod_info_advanced_conflicts"); + remove(m_Settings, "General", "mod_info_conflicts_overwrite"); + remove(m_Settings, "General", "mod_info_conflicts_noconflict"); + remove(m_Settings, "General", "mod_info_conflicts_overwritten"); } - return {}; -} - -void Settings::setManagedGameDirectory(const QString& path) -{ - set(m_Settings, "General", "gamePath", QDir::toNativeSeparators(path).toUtf8()); -} - -std::optional<QString> Settings::getManagedGameName() const -{ - return getOptional<QString>(m_Settings, "General", "gameName"); -} - -void Settings::setManagedGameName(const QString& name) -{ - set(m_Settings, "General", "gameName", name); -} - -std::optional<QString> Settings::getManagedGameEdition() const -{ - return getOptional<QString>(m_Settings, "General", "game_edition"); -} - -void Settings::setManagedGameEdition(const QString& name) -{ - set(m_Settings, "General", "game_edition", name); -} - -std::optional<QString> Settings::getSelectedProfileName() const -{ - if (auto v=getOptional<QByteArray>(m_Settings, "General", "selected_profile")) { - return QString::fromUtf8(*v); + if (lastVersion < QVersionNumber(2, 2, 2)) { + // log splitter is gone, it's a dock now + remove(m_Settings, "General", "log_split"); } - return {}; -} - -void Settings::setSelectedProfileName(const QString& name) -{ - set(m_Settings, "General", "selected_profile", name.toUtf8()); -} - -std::optional<QString> Settings::getStyleName() const -{ - return getOptional<QString>(m_Settings, "Settings", "style"); + //save version in all case + set(m_Settings, "General", "version", currentVersion.toString()); } -void Settings::setStyleName(const QString& name) +QString Settings::filename() const { - set(m_Settings, "Settings", "style", name); + return m_Settings.fileName(); } -bool Settings::getUseProxy() const +bool Settings::usePrereleases() const { - return get<bool>(m_Settings, "Settings", "use_proxy", false); + return get<bool>(m_Settings, "Settings", "use_prereleases", false); } -void Settings::setUseProxy(bool b) +void Settings::setUsePrereleases(bool b) { - set(m_Settings, "Settings", "use_proxy", b); + set(m_Settings, "Settings", "use_prereleases", b); } -std::optional<QVersionNumber> Settings::getVersion() const +std::optional<QVersionNumber> Settings::version() const { if (auto v=getOptional<QString>(m_Settings, "General", "version")) { return QVersionNumber::fromString(*v).normalized(); @@ -864,7 +599,7 @@ std::optional<QVersionNumber> Settings::getVersion() const return {}; } -bool Settings::getFirstStart() const +bool Settings::firstStart() const { return get<bool>(m_Settings, "General", "first_start", true); } @@ -874,679 +609,362 @@ void Settings::setFirstStart(bool b) set(m_Settings, "General", "first_start", b); } -std::optional<QColor> Settings::getPreviousSeparatorColor() const +QString Settings::executablesBlacklist() const { - const auto c = getOptional<QColor>(m_Settings, "General", "previousSeparatorColor"); - if (c && c->isValid()) { - return c; - } - - return {}; -} + static const QString def = (QStringList() + << "Chrome.exe" + << "Firefox.exe" + << "TSVNCache.exe" + << "TGitCache.exe" + << "Steam.exe" + << "GameOverlayUI.exe" + << "Discord.exe" + << "GalaxyClient.exe" + << "Spotify.exe" + ).join(";"); -void Settings::setPreviousSeparatorColor(const QColor& c) const -{ - set(m_Settings, "General", "previousSeparatorColor", c); + return get<QString>(m_Settings, "Settings", "executable_blacklist", def); } -void Settings::removePreviousSeparatorColor() +void Settings::setExecutablesBlacklist(const QString& s) { - remove(m_Settings, "General", "previousSeparatorColor"); + set(m_Settings, "Settings", "executable_blacklist", s); } -bool Settings::getNexusApiKey(QString &apiKey) const +void Settings::setMotdHash(uint hash) { - QString tempKey = deObfuscate("APIKEY"); - if (tempKey.isEmpty()) - return false; - - apiKey = tempKey; - return true; + set(m_Settings, "General", "motd_hash", hash); } -bool Settings::setNexusApiKey(const QString& apiKey) +unsigned int Settings::motdHash() const { - if (!obfuscate("APIKEY", apiKey)) { - const auto e = GetLastError(); - log::error("Storing API key failed: {}", formatSystemMessage(e)); - return false; - } - - return true; + return get<unsigned int>(m_Settings, "General", "motd_hash", 0); } -bool Settings::clearNexusApiKey() +bool Settings::archiveParsing() const { - return setNexusApiKey(""); + return get<bool>(m_Settings, "Settings", "archive_parsing_experimental", false); } -bool Settings::hasNexusApiKey() const +void Settings::setArchiveParsing(bool b) { - return !deObfuscate("APIKEY").isEmpty(); + set(m_Settings, "Settings", "archive_parsing_experimental", b); } -bool Settings::getSteamLogin(QString &username, QString &password) const +std::vector<std::map<QString, QVariant>> Settings::executables() const { - username = get<QString>(m_Settings, "Settings", "steam_username", ""); - password = deObfuscate("steam_password"); - - return !username.isEmpty() && !password.isEmpty(); -} + ScopedReadArray sra(m_Settings, "customExecutables"); + std::vector<std::map<QString, QVariant>> v; -bool Settings::compactDownloads() const -{ - return get<bool>(m_Settings, "Settings", "compact_downloads", false); -} + sra.for_each([&]{ + std::map<QString, QVariant> map; -void Settings::setCompactDownloads(bool b) -{ - set(m_Settings, "Settings", "compact_downloads", b); -} + for (auto&& key : sra.keys()) { + map[key] = m_Settings.value(key); + } -bool Settings::metaDownloads() const -{ - return get<bool>(m_Settings, "Settings", "meta_downloads", false); -} + v.push_back(map); + }); -void Settings::setMetaDownloads(bool b) -{ - set(m_Settings, "Settings", "meta_downloads", b); + return v; } -bool Settings::offlineMode() const +void Settings::setExecutables(const std::vector<std::map<QString, QVariant>>& v) { - return get<bool>(m_Settings, "Settings/offline_mode", false); -} + removeSection(m_Settings, "customExecutables"); -void Settings::setOfflineMode(bool b) -{ - set(m_Settings, "Settings", "offline_mode", b); -} + ScopedWriteArray swa(m_Settings, "customExecutables"); -log::Levels Settings::logLevel() const -{ - return get<log::Levels>(m_Settings, "Settings", "log_level", log::Levels::Info); -} + for (const auto& map : v) { + swa.next(); -void Settings::setLogLevel(log::Levels level) -{ - set(m_Settings, "Settings", "log_level", level); + for (auto&& p : map) { + swa.set(p.first, p.second); + } + } } -CrashDumpsType Settings::crashDumpsType() const +bool Settings::keepBackupOnInstall() const { - return get<CrashDumpsType>(m_Settings, - "Settings", "crash_dumps_type", CrashDumpsType::Mini); + return get<bool>(m_Settings, "General", "backup_install", false); } -void Settings::setCrashDumpsType(CrashDumpsType type) +void Settings::setKeepBackupOnInstall(bool b) { - set(m_Settings, "Settings", "crash_dumps_type", type); + set(m_Settings, "General", "backup_install", b); } -int Settings::crashDumpsMax() const +GameSettings& Settings::game() { - return get<int>(m_Settings, "Settings", "crash_dumps_max", 5); + return m_Game; } -void Settings::setCrashDumpsMax(int n) +const GameSettings& Settings::game() const { - set(m_Settings, "Settings", "crash_dumps_max", n); + return m_Game; } -QString Settings::executablesBlacklist() const +GeometrySettings& Settings::geometry() { - static const QString def = (QStringList() - << "Chrome.exe" - << "Firefox.exe" - << "TSVNCache.exe" - << "TGitCache.exe" - << "Steam.exe" - << "GameOverlayUI.exe" - << "Discord.exe" - << "GalaxyClient.exe" - << "Spotify.exe" - ).join(";"); - - return get<QString>(m_Settings, "Settings", "executable_blacklist", def); + return m_Geometry; } -void Settings::setExecutablesBlacklist(const QString& s) +const GeometrySettings& Settings::geometry() const { - set(m_Settings, "Settings", "executable_blacklist", s); + return m_Geometry; } -void Settings::setSteamLogin(QString username, QString password) +WidgetSettings& Settings::widgets() { - if (username == "") { - remove(m_Settings, "Settings", "steam_username"); - password = ""; - } else { - set(m_Settings, "Settings", "steam_username", username); - } - - if (!obfuscate("steam_password", password)) { - const auto e = GetLastError(); - log::error("Storing or deleting password failed: {}", formatSystemMessage(e)); - } + return m_Widgets; } -LoadMechanism::EMechanism Settings::getLoadMechanism() const +const WidgetSettings& Settings::widgets() const { - const auto def = LoadMechanism::LOAD_MODORGANIZER; - - const auto i = get<LoadMechanism::EMechanism>(m_Settings, - "Settings", "load_mechanism", def); - - switch (i) - { - // ok - case LoadMechanism::LOAD_MODORGANIZER: // fall-through - { - break; - } - - default: - { - log::error( - "invalid load mechanism {}, reverting to {}", - static_cast<int>(i), toString(def)); - - set(m_Settings, "Settings", "load_mechanism", def); - - return def; - } - } - - return i; + return m_Widgets; } -void Settings::setLoadMechanism(LoadMechanism::EMechanism m) +ColorSettings& Settings::colors() { - set(m_Settings, "Settings", "load_mechanism", m); + return m_Colors; } -void Settings::setupLoadMechanism() +const ColorSettings& Settings::colors() const { - m_LoadMechanism.activate(getLoadMechanism()); + return m_Colors; } -bool Settings::endorsementIntegration() const +PluginSettings& Settings::plugins() { - return get<bool>(m_Settings, "Settings", "endorsement_integration", true); + return m_Plugins; } -void Settings::setEndorsementIntegration(bool b) const +const PluginSettings& Settings::plugins() const { - set(m_Settings, "Settings", "endorsement_integration", b); + return m_Plugins; } -EndorsementState Settings::endorsementState() const +PathSettings& Settings::paths() { - return endorsementStateFromString( - get<QString>(m_Settings, "General", "endorse_state", "")); + return m_Paths; } -void Settings::setEndorsementState(EndorsementState s) +const PathSettings& Settings::paths() const { - const auto v = toString(s); - - if (v.isEmpty()) { - remove(m_Settings, "General", "endorse_state"); - } else { - set(m_Settings, "General", "endorse_state", v); - } + return m_Paths; } -bool Settings::hideAPICounter() const +NetworkSettings& Settings::network() { - return get<bool>(m_Settings, "Settings", "hide_api_counter", false); + return m_Network; } -void Settings::setHideAPICounter(bool b) +const NetworkSettings& Settings::network() const { - set(m_Settings, "Settings", "hide_api_counter", b); + return m_Network; } -bool Settings::displayForeign() const +NexusSettings& Settings::nexus() { - return get<bool>(m_Settings, "Settings", "display_foreign", true); + return m_Nexus; } -void Settings::setDisplayForeign(bool b) +const NexusSettings& Settings::nexus() const { - set(m_Settings, "Settings", "display_foreign", b); + return m_Nexus; } -void Settings::setMotDHash(uint hash) +SteamSettings& Settings::steam() { - set(m_Settings, "General", "motd_hash", hash); + return m_Steam; } -unsigned int Settings::getMotDHash() const +const SteamSettings& Settings::steam() const { - return get<unsigned int>(m_Settings, "motd_hash", 0); + return m_Steam; } -bool Settings::archiveParsing() const +InterfaceSettings& Settings::interface() { - return get<bool>(m_Settings, "Settings", "archive_parsing_experimental", false); + return m_Interface; } -void Settings::setArchiveParsing(bool b) +const InterfaceSettings& Settings::interface() const { - set(m_Settings, "Settings", "archive_parsing_experimental", b); + return m_Interface; } -QString Settings::language() +DiagnosticsSettings& Settings::diagnostics() { - QString result = get<QString>(m_Settings, "Settings", "language", ""); - - if (result.isEmpty()) { - QStringList languagePreferences = QLocale::system().uiLanguages(); - - if (languagePreferences.length() > 0) { - // the users most favoritest language - result = languagePreferences.at(0); - } else { - // fallback system locale - result = QLocale::system().name(); - } - } - - return result; + return m_Diagnostics; } -void Settings::setLanguage(const QString& name) +const DiagnosticsSettings& Settings::diagnostics() const { - set(m_Settings, "Settings", "language", name); + return m_Diagnostics; } -void Settings::setDownloadSpeed(const QString& name, int bytesPerSecond) +QSettings::Status Settings::sync() const { - auto servers = getServers(); - - for (auto& server : servers) { - if (server.name() == name) { - server.addDownload(bytesPerSecond); - updateServers(servers); - return; - } - } - - log::error( - "server '{}' not found while trying to add a download with bps {}", - name, bytesPerSecond); + m_Settings.sync(); + return m_Settings.status(); } -ServerList Settings::getServers() const +void Settings::dump() const { - // servers used to be a map of byte arrays until 2.2.1, it's now an array of - // individual values instead - // - // so post 2.2.1, only one key is returned: "size", the size of the arrays; - // in 2.2.1, one key per server is returned - { - const QStringList keys = ScopedGroup(m_Settings, "Servers").keys(); - - if (!keys.empty() && keys[0] != "size") { - // old format - return getServersFromOldMap(); - } - } - - - // post 2.2.1 format, array of values - - ServerList list; - - { - ScopedReadArray sra(m_Settings, "Servers"); - - sra.for_each([&] { - ServerInfo::SpeedList lastDownloads; - - const auto lastDownloadsString = sra.get<QString>("lastDownloads", ""); - - for (const auto& s : lastDownloadsString.split(" ")) { - const auto bytesPerSecond = s.toInt(); - if (bytesPerSecond > 0) { - lastDownloads.push_back(bytesPerSecond); - } - } - - ServerInfo server( - sra.get<QString>("name", ""), - sra.get<bool>("premium", false), - QDate::fromString(sra.get<QString>("lastSeen", ""), Qt::ISODate), - sra.get<int>("preferred", 0), - lastDownloads); - - list.add(std::move(server)); + static const QStringList ignore({ + "username", "password", "nexus_api_key" }); - } - - return list; -} - -ServerList Settings::getServersFromOldMap() const -{ - // for 2.2.1 and before - - ServerList list; - const ScopedGroup sg(m_Settings, "Servers"); - - sg.for_each([&](auto&& serverKey) { - QVariantMap data = sg.get<QVariantMap>(serverKey); - - ServerInfo server( - serverKey, - data["premium"].toBool(), - data["lastSeen"].toDate(), - data["preferred"].toInt(), - {}); - - // ignoring download count and speed, it's now a list of values instead of - // a total - - list.add(std::move(server)); - }); - - return list; -} - -void Settings::updateServers(ServerList servers) -{ - // clean up unavailable servers - servers.cleanup(); - removeSection(m_Settings, "Servers"); + log::debug("settings:"); { - ScopedWriteArray swa(m_Settings, "Servers"); - - for (const auto& server : servers) { - swa.next(); - - swa.set("name", server.name()); - swa.set("premium", server.isPremium()); - swa.set("lastSeen", server.lastSeen().toString(Qt::ISODate)); - swa.set("preferred", server.preferred()); + ScopedGroup sg(m_Settings, "Settings"); - QString lastDownloads; - for (const auto& speed : server.lastDownloads()) { - if (speed > 0) { - lastDownloads += QString("%1 ").arg(speed); - } + for (auto k : m_Settings.allKeys()) { + if (ignore.contains(k, Qt::CaseInsensitive)) { + continue; } - swa.set("lastDownloads", lastDownloads.trimmed()); + log::debug(" . {}={}", k, m_Settings.value(k).toString()); } } -} - -std::map<QString, QString> Settings::getRecentDirectories() const -{ - std::map<QString, QString> map; - - ScopedReadArray sra(m_Settings, "RecentDirectories"); - - sra.for_each([&] { - const QVariant name = sra.get<QVariant>("name"); - const QVariant dir = sra.get<QVariant>("directory"); - - if (name.isValid() && dir.isValid()) { - map.emplace(name.toString(), dir.toString()); - } - }); - return map; + m_Network.dump(); } -void Settings::setRecentDirectories(const std::map<QString, QString>& map) +void Settings::managedGameChanged(IPluginGame const *gamePlugin) { - removeSection(m_Settings, "RecentDirectories"); - - ScopedWriteArray swa(m_Settings, "recentDirectories"); - - for (auto&& p : map) { - swa.next(); - - swa.set("name", p.first); - swa.set("directory", p.second); - } + m_Game.setPlugin(gamePlugin); } -std::vector<std::map<QString, QVariant>> Settings::getExecutables() const -{ - ScopedReadArray sra(m_Settings, "customExecutables"); - std::vector<std::map<QString, QVariant>> v; - - sra.for_each([&]{ - std::map<QString, QVariant> map; - - for (auto&& key : sra.keys()) { - map[key] = m_Settings.value(key); - } - - v.push_back(map); - }); - - return v; -} -void Settings::setExecutables(const std::vector<std::map<QString, QVariant>>& v) +GameSettings::GameSettings(QSettings& settings) + : m_Settings(settings), m_GamePlugin(nullptr) { - removeSection(m_Settings, "customExecutables"); - - ScopedWriteArray swa(m_Settings, "customExecutables"); - - for (const auto& map : v) { - swa.next(); - - for (auto&& p : map) { - swa.set(p.first, p.second); - } - } } -bool Settings::isTutorialCompleted(const QString& windowName) const +const MOBase::IPluginGame* GameSettings::plugin() { - return get<bool>(m_Settings, "CompletedWindowTutorials", windowName, false); + return m_GamePlugin; } -void Settings::setTutorialCompleted(const QString& windowName, bool b) +void GameSettings::setPlugin(const MOBase::IPluginGame* gamePlugin) { - set(m_Settings, "CompletedWindowTutorials", windowName, b); + m_GamePlugin = gamePlugin; } -bool Settings::keepBackupOnInstall() const +bool GameSettings::forceEnableCoreFiles() const { - return get<bool>(m_Settings, "backup_install", false); + return get<bool>(m_Settings, "Settings", "force_enable_core_files", true); } -void Settings::setKeepBackupOnInstall(bool b) +void GameSettings::setForceEnableCoreFiles(bool b) { - set(m_Settings, "General", "backup_install", b); + set(m_Settings, "Settings", "force_enable_core_files", b); } -QuestionBoxMemory::Button Settings::getQuestionButton( - const QString& windowName, const QString& filename) const +std::optional<QString> GameSettings::directory() const { - const QString sectionName("DialogChoices"); - - if (!filename.isEmpty()) { - const auto fileSetting = windowName + "/" + filename; - if (auto v=getOptional<int>(m_Settings, sectionName, filename)) { - return static_cast<QuestionBoxMemory::Button>(*v); - } - } - - if (auto v=getOptional<int>(m_Settings, sectionName, windowName)) { - return static_cast<QuestionBoxMemory::Button>(*v); + if (auto v=getOptional<QByteArray>(m_Settings, "General", "gamePath")) { + return QString::fromUtf8(*v); } - return QuestionBoxMemory::NoButton; + return {}; } -void Settings::setQuestionWindowButton( - const QString& windowName, QuestionBoxMemory::Button button) +void GameSettings::setDirectory(const QString& path) { - const QString sectionName("DialogChoices/"); - - if (button == QuestionBoxMemory::NoButton) { - remove(m_Settings, sectionName, windowName); - } else { - set(m_Settings, sectionName, windowName, button); - } + set(m_Settings, "General", "gamePath", QDir::toNativeSeparators(path).toUtf8()); } -void Settings::setQuestionFileButton( - const QString& windowName, const QString& filename, - QuestionBoxMemory::Button button) +std::optional<QString> GameSettings::name() const { - const QString sectionName("DialogChoices"); - const QString settingName(windowName + "/" + filename); - - if (button == QuestionBoxMemory::NoButton) { - remove(m_Settings, sectionName, settingName); - } else { - set(m_Settings, sectionName, settingName, button); - } + return getOptional<QString>(m_Settings, "General", "gameName"); } -void Settings::resetQuestionButtons() +void GameSettings::setName(const QString& name) { - removeSection(m_Settings, "DialogChoices"); + set(m_Settings, "General", "gameName", name); } -std::optional<int> Settings::getIndex(const QComboBox* cb) const +std::optional<QString> GameSettings::edition() const { - return getOptional<int>(m_Settings, "Widgets", indexSettingName(cb)); + return getOptional<QString>(m_Settings, "General", "game_edition"); } -void Settings::saveIndex(const QComboBox* cb) +void GameSettings::setEdition(const QString& name) { - set(m_Settings, "Widgets", indexSettingName(cb), cb->currentIndex()); + set(m_Settings, "General", "game_edition", name); } -void Settings::restoreIndex(QComboBox* cb, std::optional<int> def) const +std::optional<QString> GameSettings::selectedProfileName() const { - if (auto v=getOptional<int>(m_Settings, "Widgets", indexSettingName(cb), def)) { - cb->setCurrentIndex(*v); + if (auto v=getOptional<QByteArray>(m_Settings, "General", "selected_profile")) { + return QString::fromUtf8(*v); } -} -std::optional<int> Settings::getIndex(const QTabWidget* w) const -{ - return getOptional<int>(m_Settings, "Widgets", indexSettingName(w)); -} - -void Settings::saveIndex(const QTabWidget* w) -{ - set(m_Settings, "Widgets", indexSettingName(w), w->currentIndex()); + return {}; } -void Settings::restoreIndex(QTabWidget* w, std::optional<int> def) const +void GameSettings::setSelectedProfileName(const QString& name) { - if (auto v=getOptional<int>(m_Settings, "Widgets", indexSettingName(w), def)) { - w->setCurrentIndex(*v); - } + set(m_Settings, "General", "selected_profile", name.toUtf8()); } -std::optional<bool> Settings::getChecked(const QAbstractButton* w) const +LoadMechanism::EMechanism GameSettings::loadMechanismType() const { - warnIfNotCheckable(w); - return getOptional<bool>(m_Settings, "Widgets", checkedSettingName(w)); -} + const auto def = LoadMechanism::LOAD_MODORGANIZER; -void Settings::saveChecked(const QAbstractButton* w) -{ - warnIfNotCheckable(w); - set(m_Settings, "Widgets", checkedSettingName(w), w->isChecked()); -} + const auto i = get<LoadMechanism::EMechanism>(m_Settings, + "Settings", "load_mechanism", def); -void Settings::restoreChecked(QAbstractButton* w, std::optional<bool> def) const -{ - warnIfNotCheckable(w); + switch (i) + { + // ok + case LoadMechanism::LOAD_MODORGANIZER: // fall-through + { + break; + } - if (auto v=getOptional<bool>(m_Settings, "Widgets", checkedSettingName(w), def)) { - w->setChecked(*v); - } -} + default: + { + log::error( + "invalid load mechanism {}, reverting to {}", + static_cast<int>(i), toString(def)); -GeometrySettings& Settings::geometry() -{ - return m_Geometry; -} + set(m_Settings, "Settings", "load_mechanism", def); -const GeometrySettings& Settings::geometry() const -{ - return m_Geometry; -} + return def; + } + } -ColorSettings& Settings::colors() -{ - return m_Colors; + return i; } -const ColorSettings& Settings::colors() const +void GameSettings::setLoadMechanism(LoadMechanism::EMechanism m) { - return m_Colors; + set(m_Settings, "Settings", "load_mechanism", m); } -PluginSettings& Settings::plugins() +const LoadMechanism& GameSettings::loadMechanism() const { - return m_Plugins; + return m_LoadMechanism; } -const PluginSettings& Settings::plugins() const +void GameSettings::setupLoadMechanism() { - return m_Plugins; + m_LoadMechanism.activate(loadMechanismType()); } -QSettings::Status Settings::sync() const +bool GameSettings::hideUncheckedPlugins() const { - m_Settings.sync(); - return m_Settings.status(); + return get<bool>(m_Settings, "Settings", "hide_unchecked_plugins", false); } -void Settings::dump() const +void GameSettings::setHideUncheckedPlugins(bool b) { - static const QStringList ignore({ - "username", "password", "nexus_api_key" - }); - - log::debug("settings:"); - - { - ScopedGroup sg(m_Settings, "Settings"); - - for (auto k : m_Settings.allKeys()) { - if (ignore.contains(k, Qt::CaseInsensitive)) { - continue; - } - - log::debug(" . {}={}", k, m_Settings.value(k).toString()); - } - } - - log::debug("servers:"); - - for (const auto& server : getServers()) { - QString lastDownloads; - for (auto speed : server.lastDownloads()) { - lastDownloads += QString("%1 ").arg(speed); - } - - log::debug( - " . {} premium={} lastSeen={} preferred={} lastDownloads={}", - server.name(), - server.isPremium() ? "yes" : "no", - server.lastSeen().toString(Qt::ISODate), - server.preferred(), - lastDownloads.trimmed()); - } + set(m_Settings, "Settings", "hide_unchecked_plugins", b); } @@ -1697,7 +1115,7 @@ void GeometrySettings::saveToolbars(const QMainWindow* w) } } -QStringList GeometrySettings::getModInfoTabOrder() const +QStringList GeometrySettings::modInfoTabOrder() const { QStringList v; @@ -1840,6 +1258,121 @@ void GeometrySettings::restoreDocks(QMainWindow* mw) const } +WidgetSettings::WidgetSettings(QSettings& s) + : m_Settings(s) +{ + MOBase::QuestionBoxMemory::setCallbacks( + [this](auto&& w, auto&& f){ return questionButton(w, f); }, + [this](auto&& w, auto&& b){ setQuestionWindowButton(w, b); }, + [this](auto&& w, auto&& f, auto&& b){ setQuestionFileButton(w, f, b); }); +} + +std::optional<int> WidgetSettings::index(const QComboBox* cb) const +{ + return getOptional<int>(m_Settings, "Widgets", indexSettingName(cb)); +} + +void WidgetSettings::saveIndex(const QComboBox* cb) +{ + set(m_Settings, "Widgets", indexSettingName(cb), cb->currentIndex()); +} + +void WidgetSettings::restoreIndex(QComboBox* cb, std::optional<int> def) const +{ + if (auto v=getOptional<int>(m_Settings, "Widgets", indexSettingName(cb), def)) { + cb->setCurrentIndex(*v); + } +} + +std::optional<int> WidgetSettings::index(const QTabWidget* w) const +{ + return getOptional<int>(m_Settings, "Widgets", indexSettingName(w)); +} + +void WidgetSettings::saveIndex(const QTabWidget* w) +{ + set(m_Settings, "Widgets", indexSettingName(w), w->currentIndex()); +} + +void WidgetSettings::restoreIndex(QTabWidget* w, std::optional<int> def) const +{ + if (auto v=getOptional<int>(m_Settings, "Widgets", indexSettingName(w), def)) { + w->setCurrentIndex(*v); + } +} + +std::optional<bool> WidgetSettings::checked(const QAbstractButton* w) const +{ + warnIfNotCheckable(w); + return getOptional<bool>(m_Settings, "Widgets", checkedSettingName(w)); +} + +void WidgetSettings::saveChecked(const QAbstractButton* w) +{ + warnIfNotCheckable(w); + set(m_Settings, "Widgets", checkedSettingName(w), w->isChecked()); +} + +void WidgetSettings::restoreChecked(QAbstractButton* w, std::optional<bool> def) const +{ + warnIfNotCheckable(w); + + if (auto v=getOptional<bool>(m_Settings, "Widgets", checkedSettingName(w), def)) { + w->setChecked(*v); + } +} + +QuestionBoxMemory::Button WidgetSettings::questionButton( + const QString& windowName, const QString& filename) const +{ + const QString sectionName("DialogChoices"); + + if (!filename.isEmpty()) { + const auto fileSetting = windowName + "/" + filename; + if (auto v=getOptional<int>(m_Settings, sectionName, filename)) { + return static_cast<QuestionBoxMemory::Button>(*v); + } + } + + if (auto v=getOptional<int>(m_Settings, sectionName, windowName)) { + return static_cast<QuestionBoxMemory::Button>(*v); + } + + return QuestionBoxMemory::NoButton; +} + +void WidgetSettings::setQuestionWindowButton( + const QString& windowName, QuestionBoxMemory::Button button) +{ + const QString sectionName("DialogChoices"); + + if (button == QuestionBoxMemory::NoButton) { + remove(m_Settings, sectionName, windowName); + } else { + set(m_Settings, sectionName, windowName, button); + } +} + +void WidgetSettings::setQuestionFileButton( + const QString& windowName, const QString& filename, + QuestionBoxMemory::Button button) +{ + const QString sectionName("DialogChoices"); + const QString settingName(windowName + "/" + filename); + + if (button == QuestionBoxMemory::NoButton) { + remove(m_Settings, sectionName, settingName); + } else { + set(m_Settings, sectionName, settingName, button); + } +} + +void WidgetSettings::resetQuestionButtons() +{ + removeSection(m_Settings, "DialogChoices"); +} + + ColorSettings::ColorSettings(QSettings& s) : m_Settings(s) { @@ -1917,6 +1450,47 @@ void ColorSettings::setPluginListContained(const QColor& c) set(m_Settings, "Settings", "containedColor", c); } +std::optional<QColor> ColorSettings::previousSeparatorColor() const +{ + const auto c = getOptional<QColor>(m_Settings, "General", "previousSeparatorColor"); + if (c && c->isValid()) { + return c; + } + + return {}; +} + +void ColorSettings::setPreviousSeparatorColor(const QColor& c) const +{ + set(m_Settings, "General", "previousSeparatorColor", c); +} + +void ColorSettings::removePreviousSeparatorColor() +{ + remove(m_Settings, "General", "previousSeparatorColor"); +} + +bool ColorSettings::colorSeparatorScrollbar() const +{ + return get<bool>(m_Settings, "Settings", "colorSeparatorScrollbars", true); +} + +void ColorSettings::setColorSeparatorScrollbar(bool b) +{ + set(m_Settings, "Settings", "colorSeparatorScrollbars", b); +} + +QColor ColorSettings::idealTextColor(const QColor& rBackgroundColor) +{ + if (rBackgroundColor.alpha() == 0) + return QColor(Qt::black); + + const int THRESHOLD = 106 * 255.0f / rBackgroundColor.alpha(); + int BackgroundDelta = (rBackgroundColor.red() * 0.299) + (rBackgroundColor.green() * 0.587) + (rBackgroundColor.blue() * 0.114); + return QColor((255 - BackgroundDelta <= THRESHOLD) ? Qt::black : Qt::white); +} + + PluginSettings::PluginSettings(QSettings& settings) : m_Settings(settings) @@ -2089,6 +1663,585 @@ void PluginSettings::save() } +PathSettings::PathSettings(QSettings& settings) + : m_Settings(settings) +{ +} + +std::map<QString, QString> PathSettings::recent() const +{ + std::map<QString, QString> map; + + ScopedReadArray sra(m_Settings, "RecentDirectories"); + + sra.for_each([&] { + const QVariant name = sra.get<QVariant>("name"); + const QVariant dir = sra.get<QVariant>("directory"); + + if (name.isValid() && dir.isValid()) { + map.emplace(name.toString(), dir.toString()); + } + }); + + return map; +} + +void PathSettings::setRecent(const std::map<QString, QString>& map) +{ + removeSection(m_Settings, "RecentDirectories"); + + ScopedWriteArray swa(m_Settings, "recentDirectories"); + + for (auto&& p : map) { + swa.next(); + + swa.set("name", p.first); + swa.set("directory", p.second); + } +} + +QString PathSettings::getConfigurablePath(const QString &key, + const QString &def, + bool resolve) const +{ + QString result = QDir::fromNativeSeparators( + get<QString>(m_Settings, "Settings", key, QString("%BASE_DIR%/") + def)); + + if (resolve) { + result.replace("%BASE_DIR%", base()); + } + + return result; +} + +void PathSettings::setConfigurablePath(const QString &key, const QString& path) +{ + if (path.isEmpty()) { + remove(m_Settings, "Settings", key); + } else { + set(m_Settings, "Settings", key, path); + } +} + +QString PathSettings::base() const +{ + return QDir::fromNativeSeparators(get<QString>(m_Settings, + "Settings", "base_directory", qApp->property("dataPath").toString())); +} + +QString PathSettings::downloads(bool resolve) const +{ + return getConfigurablePath( + "download_directory", + ToQString(AppConfig::downloadPath()), + resolve); +} + +QString PathSettings::cache(bool resolve) const +{ + return getConfigurablePath( + "cache_directory", + ToQString(AppConfig::cachePath()), + resolve); +} + +QString PathSettings::mods(bool resolve) const +{ + return getConfigurablePath( + "mod_directory", + ToQString(AppConfig::modsPath()), + resolve); +} + +QString PathSettings::profiles(bool resolve) const +{ + return getConfigurablePath( + "profiles_directory", + ToQString(AppConfig::profilesPath()), + resolve); +} + +QString PathSettings::overwrite(bool resolve) const +{ + return getConfigurablePath( + "overwrite_directory", + ToQString(AppConfig::overwritePath()), + resolve); +} + +void PathSettings::setBase(const QString& path) +{ + if (path.isEmpty()) { + remove(m_Settings, "Settings", "base_directory"); + } else { + set(m_Settings, "Settings", "base_directory", path); + } +} + +void PathSettings::setDownloads(const QString& path) +{ + setConfigurablePath("download_directory", path); +} + +void PathSettings::setMods(const QString& path) +{ + setConfigurablePath("mod_directory", path); +} + +void PathSettings::setCache(const QString& path) +{ + setConfigurablePath("cache_directory", path); +} + +void PathSettings::setProfiles(const QString& path) +{ + setConfigurablePath("profiles_directory", path); +} + +void PathSettings::setOverwrite(const QString& path) +{ + setConfigurablePath("overwrite_directory", path); +} + + +NetworkSettings::NetworkSettings(QSettings& settings) + : m_Settings(settings) +{ +} + +bool NetworkSettings::offlineMode() const +{ + return get<bool>(m_Settings, "Settings", "offline_mode", false); +} + +void NetworkSettings::setOfflineMode(bool b) +{ + set(m_Settings, "Settings", "offline_mode", b); +} + +bool NetworkSettings::useProxy() const +{ + return get<bool>(m_Settings, "Settings", "use_proxy", false); +} + +void NetworkSettings::setUseProxy(bool b) +{ + set(m_Settings, "Settings", "use_proxy", b); +} + +void NetworkSettings::setDownloadSpeed(const QString& name, int bytesPerSecond) +{ + auto current = servers(); + + for (auto& server : current) { + if (server.name() == name) { + server.addDownload(bytesPerSecond); + updateServers(current); + return; + } + } + + log::error( + "server '{}' not found while trying to add a download with bps {}", + name, bytesPerSecond); +} + +ServerList NetworkSettings::servers() const +{ + // servers used to be a map of byte arrays until 2.2.1, it's now an array of + // individual values instead + // + // so post 2.2.1, only one key is returned: "size", the size of the arrays; + // in 2.2.1, one key per server is returned + { + const QStringList keys = ScopedGroup(m_Settings, "Servers").keys(); + + if (!keys.empty() && keys[0] != "size") { + // old format + return serversFromOldMap(); + } + } + + + // post 2.2.1 format, array of values + + ServerList list; + + { + ScopedReadArray sra(m_Settings, "Servers"); + + sra.for_each([&] { + ServerInfo::SpeedList lastDownloads; + + const auto lastDownloadsString = sra.get<QString>("lastDownloads", ""); + + for (const auto& s : lastDownloadsString.split(" ")) { + const auto bytesPerSecond = s.toInt(); + if (bytesPerSecond > 0) { + lastDownloads.push_back(bytesPerSecond); + } + } + + ServerInfo server( + sra.get<QString>("name", ""), + sra.get<bool>("premium", false), + QDate::fromString(sra.get<QString>("lastSeen", ""), Qt::ISODate), + sra.get<int>("preferred", 0), + lastDownloads); + + list.add(std::move(server)); + }); + } + + return list; +} + +ServerList NetworkSettings::serversFromOldMap() const +{ + // for 2.2.1 and before + + ServerList list; + const ScopedGroup sg(m_Settings, "Servers"); + + sg.for_each([&](auto&& serverKey) { + QVariantMap data = sg.get<QVariantMap>(serverKey); + + ServerInfo server( + serverKey, + data["premium"].toBool(), + data["lastSeen"].toDate(), + data["preferred"].toInt(), + {}); + + // ignoring download count and speed, it's now a list of values instead of + // a total + + list.add(std::move(server)); + }); + + return list; +} + +void NetworkSettings::updateServers(ServerList servers) +{ + // clean up unavailable servers + servers.cleanup(); + + removeSection(m_Settings, "Servers"); + + { + ScopedWriteArray swa(m_Settings, "Servers"); + + for (const auto& server : servers) { + swa.next(); + + swa.set("name", server.name()); + swa.set("premium", server.isPremium()); + swa.set("lastSeen", server.lastSeen().toString(Qt::ISODate)); + swa.set("preferred", server.preferred()); + + QString lastDownloads; + for (const auto& speed : server.lastDownloads()) { + if (speed > 0) { + lastDownloads += QString("%1 ").arg(speed); + } + } + + swa.set("lastDownloads", lastDownloads.trimmed()); + } + } +} + +void NetworkSettings::dump() const +{ + log::debug("servers:"); + + for (const auto& server : servers()) { + QString lastDownloads; + for (auto speed : server.lastDownloads()) { + lastDownloads += QString("%1 ").arg(speed); + } + + log::debug( + " . {} premium={} lastSeen={} preferred={} lastDownloads={}", + server.name(), + server.isPremium() ? "yes" : "no", + server.lastSeen().toString(Qt::ISODate), + server.preferred(), + lastDownloads.trimmed()); + } +} + + +NexusSettings::NexusSettings(Settings& parent, QSettings& settings) + : m_Parent(parent), m_Settings(settings) +{ +} + +bool NexusSettings::automaticLoginEnabled() const +{ + return get<bool>(m_Settings, "Settings", "nexus_login", false); +} + +bool NexusSettings::apiKey(QString &apiKey) const +{ + QString tempKey = getWindowsCredential("APIKEY"); + if (tempKey.isEmpty()) + return false; + + apiKey = tempKey; + return true; +} + +bool NexusSettings::setApiKey(const QString& apiKey) +{ + if (!setWindowsCredential("APIKEY", apiKey)) { + const auto e = GetLastError(); + log::error("Storing API key failed: {}", formatSystemMessage(e)); + return false; + } + + return true; +} + +bool NexusSettings::clearApiKey() +{ + return setApiKey(""); +} + +bool NexusSettings::hasApiKey() const +{ + return !getWindowsCredential("APIKEY").isEmpty(); +} + +bool NexusSettings::endorsementIntegration() const +{ + return get<bool>(m_Settings, "Settings", "endorsement_integration", true); +} + +void NexusSettings::setEndorsementIntegration(bool b) const +{ + set(m_Settings, "Settings", "endorsement_integration", b); +} + +EndorsementState NexusSettings::endorsementState() const +{ + return endorsementStateFromString( + get<QString>(m_Settings, "General", "endorse_state", "")); +} + +void NexusSettings::setEndorsementState(EndorsementState s) +{ + const auto v = toString(s); + + if (v.isEmpty()) { + remove(m_Settings, "General", "endorse_state"); + } else { + set(m_Settings, "General", "endorse_state", v); + } +} + +void NexusSettings::registerAsNXMHandler(bool force) +{ + const auto nxmPath = QCoreApplication::applicationDirPath() + "/nxmhandler.exe"; + const auto executable = QCoreApplication::applicationFilePath(); + + QString mode = force ? "forcereg" : "reg"; + QString parameters = mode + " " + m_Parent.game().plugin()->gameShortName(); + for (const QString& altGame : m_Parent.game().plugin()->validShortNames()) { + parameters += "," + altGame; + } + parameters += " \"" + executable + "\""; + + if (!shell::Execute(nxmPath, parameters)) { + QMessageBox::critical( + nullptr, QObject::tr("Failed"), + QObject::tr("Failed to start the helper application")); + } +} + + +SteamSettings::SteamSettings(Settings& parent, QSettings& settings) + : m_Parent(parent), m_Settings(settings) +{ +} + +QString SteamSettings::appID() const +{ + return get<QString>( + m_Settings, "Settings", "app_id", m_Parent.game().plugin()->steamAPPId()); +} + +void SteamSettings::setAppID(const QString& id) +{ + if (id.isEmpty()) { + remove(m_Settings, "Settings", "app_id"); + } else { + set(m_Settings, "Settings", "app_id", id); + } +} + +bool SteamSettings::login(QString &username, QString &password) const +{ + username = get<QString>(m_Settings, "Settings", "steam_username", ""); + password = getWindowsCredential("steam_password"); + + return !username.isEmpty() && !password.isEmpty(); +} + +void SteamSettings::setLogin(QString username, QString password) +{ + if (username == "") { + remove(m_Settings, "Settings", "steam_username"); + password = ""; + } else { + set(m_Settings, "Settings", "steam_username", username); + } + + if (!setWindowsCredential("steam_password", password)) { + const auto e = GetLastError(); + log::error("Storing or deleting password failed: {}", formatSystemMessage(e)); + } +} + + +InterfaceSettings::InterfaceSettings(QSettings& settings) + : m_Settings(settings) +{ +} + +bool InterfaceSettings::lockGUI() const +{ + return get<bool>(m_Settings, "Settings", "lock_gui", true); +} + +void InterfaceSettings::setLockGUI(bool b) +{ + set(m_Settings, "Settings", "lock_gui", b); +} + +std::optional<QString> InterfaceSettings::styleName() const +{ + return getOptional<QString>(m_Settings, "Settings", "style"); +} + +void InterfaceSettings::setStyleName(const QString& name) +{ + set(m_Settings, "Settings", "style", name); +} + +bool InterfaceSettings::compactDownloads() const +{ + return get<bool>(m_Settings, "Settings", "compact_downloads", false); +} + +void InterfaceSettings::setCompactDownloads(bool b) +{ + set(m_Settings, "Settings", "compact_downloads", b); +} + +bool InterfaceSettings::metaDownloads() const +{ + return get<bool>(m_Settings, "Settings", "meta_downloads", false); +} + +void InterfaceSettings::setMetaDownloads(bool b) +{ + set(m_Settings, "Settings", "meta_downloads", b); +} + +bool InterfaceSettings::hideAPICounter() const +{ + return get<bool>(m_Settings, "Settings", "hide_api_counter", false); +} + +void InterfaceSettings::setHideAPICounter(bool b) +{ + set(m_Settings, "Settings", "hide_api_counter", b); +} + +bool InterfaceSettings::displayForeign() const +{ + return get<bool>(m_Settings, "Settings", "display_foreign", true); +} + +void InterfaceSettings::setDisplayForeign(bool b) +{ + set(m_Settings, "Settings", "display_foreign", b); +} + +QString InterfaceSettings::language() +{ + QString result = get<QString>(m_Settings, "Settings", "language", ""); + + if (result.isEmpty()) { + QStringList languagePreferences = QLocale::system().uiLanguages(); + + if (languagePreferences.length() > 0) { + // the users most favoritest language + result = languagePreferences.at(0); + } else { + // fallback system locale + result = QLocale::system().name(); + } + } + + return result; +} + +void InterfaceSettings::setLanguage(const QString& name) +{ + set(m_Settings, "Settings", "language", name); +} + +bool InterfaceSettings::isTutorialCompleted(const QString& windowName) const +{ + return get<bool>(m_Settings, "CompletedWindowTutorials", windowName, false); +} + +void InterfaceSettings::setTutorialCompleted(const QString& windowName, bool b) +{ + set(m_Settings, "CompletedWindowTutorials", windowName, b); +} + + +DiagnosticsSettings::DiagnosticsSettings(QSettings& settings) + : m_Settings(settings) +{ +} + +log::Levels DiagnosticsSettings::logLevel() const +{ + return get<log::Levels>(m_Settings, "Settings", "log_level", log::Levels::Info); +} + +void DiagnosticsSettings::setLogLevel(log::Levels level) +{ + set(m_Settings, "Settings", "log_level", level); +} + +CrashDumpsType DiagnosticsSettings::crashDumpsType() const +{ + return get<CrashDumpsType>(m_Settings, + "Settings", "crash_dumps_type", CrashDumpsType::Mini); +} + +void DiagnosticsSettings::setCrashDumpsType(CrashDumpsType type) +{ + set(m_Settings, "Settings", "crash_dumps_type", type); +} + +int DiagnosticsSettings::crashDumpsMax() const +{ + return get<int>(m_Settings, "Settings", "crash_dumps_max", 5); +} + +void DiagnosticsSettings::setCrashDumpsMax(int n) +{ + set(m_Settings, "Settings", "crash_dumps_max", n); +} + + GeometrySaver::GeometrySaver(Settings& s, QDialog* dialog) : m_settings(s), m_dialog(dialog) { diff --git a/src/settings.h b/src/settings.h index 403c2d71..5c0a2542 100644 --- a/src/settings.h +++ b/src/settings.h @@ -25,6 +25,10 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. #include <log.h> #include <usvfsparameters.h> +#ifdef interface + #undef interface +#endif + namespace MOBase { class IPlugin; class IPluginGame; @@ -50,6 +54,58 @@ private: }; +class GameSettings +{ +public: + GameSettings(QSettings& setting); + + const MOBase::IPluginGame* plugin(); + void setPlugin(const MOBase::IPluginGame* gamePlugin); + + /** + * whether files of the core game are forced-enabled so the user can't + * accidentally disable them + */ + bool forceEnableCoreFiles() const; + void setForceEnableCoreFiles(bool b); + + /** + * the directory where the managed game is stored (with native separators) + **/ + std::optional<QString> directory() const; + void setDirectory(const QString& path); + + std::optional<QString> name() const; + void setName(const QString& name); + + std::optional<QString> edition() const; + void setEdition(const QString& name); + + std::optional<QString> selectedProfileName() const; + void setSelectedProfileName(const QString& name); + + /** + * @return the load mechanism to be used + **/ + LoadMechanism::EMechanism loadMechanismType() const; + void setLoadMechanism(LoadMechanism::EMechanism m); + const LoadMechanism& loadMechanism() const; + void setupLoadMechanism(); + + /** + * @return true if the user wants unchecked plugins (esp, esm) should be hidden from + * the virtual data directory + **/ + bool hideUncheckedPlugins() const; + void setHideUncheckedPlugins(bool b); + +private: + QSettings& m_Settings; + const MOBase::IPluginGame* m_GamePlugin; + LoadMechanism m_LoadMechanism; +}; + + class GeometrySettings { public: @@ -83,7 +139,7 @@ public: void saveDocks(const QMainWindow* w); void restoreDocks(QMainWindow* w) const; - QStringList getModInfoTabOrder() const; + QStringList modInfoTabOrder() const; void setModInfoTabOrder(const QString& names); void centerOnMainWindowMonitor(QWidget* w); @@ -95,6 +151,40 @@ private: }; +class WidgetSettings +{ +public: + WidgetSettings(QSettings& s); + + std::optional<int> index(const QComboBox* cb) const; + void saveIndex(const QComboBox* cb); + void restoreIndex(QComboBox* cb, std::optional<int> def={}) const; + + std::optional<int> index(const QTabWidget* w) const; + void saveIndex(const QTabWidget* w); + void restoreIndex(QTabWidget* w, std::optional<int> def={}) const; + + std::optional<bool> checked(const QAbstractButton* w) const; + void saveChecked(const QAbstractButton* w); + void restoreChecked(QAbstractButton* w, std::optional<bool> def={}) const; + + MOBase::QuestionBoxMemory::Button questionButton( + const QString& windowName, const QString& filename) const; + + void setQuestionWindowButton( + const QString& windowName, MOBase::QuestionBoxMemory::Button button); + + void setQuestionFileButton( + const QString& windowName, const QString& filename, + MOBase::QuestionBoxMemory::Button choice); + + void resetQuestionButtons(); + +private: + QSettings& m_Settings; +}; + + class ColorSettings { public: @@ -120,6 +210,19 @@ public: QColor pluginListContained() const; void setPluginListContained(const QColor& c) ; + std::optional<QColor> previousSeparatorColor() const; + void setPreviousSeparatorColor(const QColor& c) const; + void removePreviousSeparatorColor(); + + /** + * @brief color the scrollbar of the mod list for custom separator colors? + * @return the state of the setting + */ + bool colorSeparatorScrollbar() const; + void setColorSeparatorScrollbar(bool b); + + static QColor idealTextColor(const QColor& rBackgroundColor); + private: QSettings& m_Settings; }; @@ -165,209 +268,228 @@ private: }; -enum class EndorsementState +class PathSettings { - Accepted = 1, - Refused, - NoDecision -}; +public: + PathSettings(QSettings& settings); -EndorsementState endorsementStateFromString(const QString& s); -QString toString(EndorsementState s); + QString base() const; + QString downloads(bool resolve = true) const; + QString mods(bool resolve = true) const; + QString cache(bool resolve = true) const; + QString profiles(bool resolve = true) const; + QString overwrite(bool resolve = true) const; + void setBase(const QString& path); + void setDownloads(const QString& path); + void setMods(const QString& path); + void setCache(const QString& path); + void setProfiles(const QString& path); + void setOverwrite(const QString& path); -/** - * manages the settings for Mod Organizer. The settings are not cached - * inside the class but read/written directly from/to disc - **/ -class Settings : public QObject -{ - Q_OBJECT; + std::map<QString, QString> recent() const; + void setRecent(const std::map<QString, QString>& map); -public: - Settings(const QString& path); - ~Settings(); +private: + QSettings& m_Settings; - static Settings &instance(); + QString getConfigurablePath(const QString &key, const QString &def, bool resolve) const; + void setConfigurablePath(const QString &key, const QString& path); +}; - void processUpdates( - const QVersionNumber& currentVersion, const QVersionNumber& lastVersion); - QString getFilename() const; +class NetworkSettings +{ +public: + NetworkSettings(QSettings& settings); /** - * @return true if the user wants unchecked plugins (esp, esm) should be hidden from - * the virtual dat adirectory - **/ - bool hideUncheckedPlugins() const; - void setHideUncheckedPlugins(bool b); + * @return true if the user disabled internet features + */ + bool offlineMode() const; + void setOfflineMode(bool b); /** - * @return true if files of the core game are forced-enabled so the user can't accidentally disable them - */ - bool forceEnableCoreFiles() const; - void setForceEnableCoreFiles(bool b); + * @return true if the user configured the use of a network proxy + */ + bool useProxy() const; + void setUseProxy(bool b); - /** - * @return true if the GUI should be locked when running executables - */ - bool lockGUI() const; - void setLockGUI(bool b); + void setDownloadSpeed(const QString &serverName, int bytesPerSecond); + ServerList servers() const; + void updateServers(ServerList servers); - /** - * the steam appid is assigned by the steam platform to each product sold there. - * The appid may differ between different versions of a game so it may be impossible - * for Mod Organizer to automatically recognize it, though usually it does - * @return the steam appid for the game - **/ - QString getSteamAppID() const; - void setSteamAppID(const QString& id); + void dump() const; - QString getBaseDirectory() const; - QString getDownloadDirectory(bool resolve = true) const; - QString getModDirectory(bool resolve = true) const; - QString getCacheDirectory(bool resolve = true) const; - QString getProfileDirectory(bool resolve = true) const; - QString getOverwriteDirectory(bool resolve = true) const; +private: + QSettings& m_Settings; - void setBaseDirectory(const QString& path); - void setDownloadDirectory(const QString& path); - void setModDirectory(const QString& path); - void setCacheDirectory(const QString& path); - void setProfileDirectory(const QString& path); - void setOverwriteDirectory(const QString& path); + ServerList serversFromOldMap() const; +}; - /** - * retrieve the directory where the managed game is stored (with native separators) - **/ - std::optional<QString> getManagedGameDirectory() const; - void setManagedGameDirectory(const QString& path); - std::optional<QString> getManagedGameName() const; - void setManagedGameName(const QString& name); +enum class EndorsementState +{ + Accepted = 1, + Refused, + NoDecision +}; - std::optional<QString> getManagedGameEdition() const; - void setManagedGameEdition(const QString& name); +EndorsementState endorsementStateFromString(const QString& s); +QString toString(EndorsementState s); - std::optional<QString> getSelectedProfileName() const; - void setSelectedProfileName(const QString& name); +class NexusSettings +{ +public: + NexusSettings(Settings& parent, QSettings& settings); - std::optional<QString> getStyleName() const; - void setStyleName(const QString& name); + /** + * @return true if the user has set up automatic login to nexus + **/ + bool automaticLoginEnabled() const; - std::optional<QVersionNumber> getVersion() const; + /** + * @brief retrieve the login information for nexus + * + * @param username (out) receives the user name for nexus + * @param password (out) received the password for nexus + * @return true if automatic login is active, false otherwise + **/ + bool apiKey(QString &apiKey) const; - bool getFirstStart() const; - void setFirstStart(bool b); + /** + * @brief set the nexus login information + * + * @param username username + * @param password password + */ + bool setApiKey(const QString& apiKey); - std::optional<QColor> getPreviousSeparatorColor() const; - void setPreviousSeparatorColor(const QColor& c) const; - void removePreviousSeparatorColor(); + /** + * @brief clears the nexus login information + */ + bool clearApiKey(); - std::map<QString, QString> getRecentDirectories() const; - void setRecentDirectories(const std::map<QString, QString>& map); + /** + * @brief returns whether an API key is currently stored + */ + bool hasApiKey() const; - std::vector<std::map<QString, QVariant>> getExecutables() const; - void setExecutables(const std::vector<std::map<QString, QVariant>>& v); + /** + * @return true if endorsement integration is enabled + */ + bool endorsementIntegration() const; + void setEndorsementIntegration(bool b) const; - bool isTutorialCompleted(const QString& windowName) const; - void setTutorialCompleted(const QString& windowName, bool b=true); + EndorsementState endorsementState() const; + void setEndorsementState(EndorsementState s); - bool keepBackupOnInstall() const; - void setKeepBackupOnInstall(bool b); + /** + * @brief register MO as the handler for nxm links + * @param force set to true to enforce the registration dialog to show up, + * even if the user said earlier not to + */ + void registerAsNXMHandler(bool force); - MOBase::QuestionBoxMemory::Button getQuestionButton( - const QString& windowName, const QString& filename) const; +private: + Settings& m_Parent; + QSettings& m_Settings; +}; - void setQuestionWindowButton( - const QString& windowName, MOBase::QuestionBoxMemory::Button button); - void setQuestionFileButton( - const QString& windowName, const QString& filename, - MOBase::QuestionBoxMemory::Button choice); +class SteamSettings +{ +public: + SteamSettings(Settings& parent, QSettings& settings); - void resetQuestionButtons(); + /** + * the steam appid is assigned by the steam platform to each product sold there. + * The appid may differ between different versions of a game so it may be impossible + * for Mod Organizer to automatically recognize it, though usually it does + * @return the steam appid for the game + **/ + QString appID() const; + void setAppID(const QString& id); - std::optional<int> getIndex(const QComboBox* cb) const; - void saveIndex(const QComboBox* cb); - void restoreIndex(QComboBox* cb, std::optional<int> def={}) const; + /** + * @brief retrieve the login information for steam + * + * @param username (out) receives the user name for nexus + * @param password (out) received the password for nexus + * @return true if a username has been specified, false otherwise + **/ + bool login(QString &username, QString &password) const; - std::optional<int> getIndex(const QTabWidget* w) const; - void saveIndex(const QTabWidget* w); - void restoreIndex(QTabWidget* w, std::optional<int> def={}) const; + /** + * @brief set the steam login information + * + * @param username username + * @param password password + */ + void setLogin(QString username, QString password); - std::optional<bool> getChecked(const QAbstractButton* w) const; - void saveChecked(const QAbstractButton* w); - void restoreChecked(QAbstractButton* w, std::optional<bool> def={}) const; +private: + Settings& m_Parent; + QSettings& m_Settings; +}; - GeometrySettings& geometry(); - const GeometrySettings& geometry() const; - ColorSettings& colors(); - const ColorSettings& colors() const; +class InterfaceSettings +{ +public: + InterfaceSettings(QSettings& settings); - PluginSettings& plugins(); - const PluginSettings& plugins() const; + /** + * @return true if the GUI should be locked when running executables + */ + bool lockGUI() const; + void setLockGUI(bool b); + std::optional<QString> styleName() const; + void setStyleName(const QString& name); /** - * @return true if the user has set up automatic login to nexus - **/ - bool automaticLoginEnabled() const; + * @return true if the user chose compact downloads + */ + bool compactDownloads() const; + void setCompactDownloads(bool b); /** - * @brief retrieve the login information for nexus - * - * @param username (out) receives the user name for nexus - * @param password (out) received the password for nexus - * @return true if automatic login is active, false otherwise - **/ - bool getNexusApiKey(QString &apiKey) const; + * @return true if the user chose meta downloads + */ + bool metaDownloads() const; + void setMetaDownloads(bool b); /** - * @brief set the nexus login information - * - * @param username username - * @param password password + * @return true if the API counter should be hidden */ - bool setNexusApiKey(const QString& apiKey); + bool hideAPICounter() const; + void setHideAPICounter(bool b); /** - * @brief clears the nexus login information + * @return true if the user wants to see non-official plugins installed outside MO in his mod list */ - bool clearNexusApiKey(); + bool displayForeign() const; + void setDisplayForeign(bool b); /** - * @brief returns whether an API key is currently stored - */ - bool hasNexusApiKey() const; + * @return short code of the configured language (corresponding to the translation files) + */ + QString language(); + void setLanguage(const QString& name); - /** - * @brief retrieve the login information for steam - * - * @param username (out) receives the user name for nexus - * @param password (out) received the password for nexus - * @return true if a username has been specified, false otherwise - **/ - bool getSteamLogin(QString &username, QString &password) const; + bool isTutorialCompleted(const QString& windowName) const; + void setTutorialCompleted(const QString& windowName, bool b=true); - /** - * @return true if the user disabled internet features - */ - bool offlineMode() const; - void setOfflineMode(bool b); +private: + QSettings& m_Settings; +}; - /** - * @return true if the user chose compact downloads - */ - bool compactDownloads() const; - void setCompactDownloads(bool b); - /** - * @return true if the user chose meta downloads - */ - bool metaDownloads() const; - void setMetaDownloads(bool b); +class DiagnosticsSettings +{ +public: + DiagnosticsSettings(QSettings& settings); MOBase::log::Levels logLevel() const; void setLogLevel(MOBase::log::Levels level); @@ -378,60 +500,48 @@ public: int crashDumpsMax() const; void setCrashDumpsMax(int n); - QString executablesBlacklist() const; - void setExecutablesBlacklist(const QString& s); +private: + QSettings& m_Settings; +}; - /** - * @brief set the steam login information - * - * @param username username - * @param password password - */ - void setSteamLogin(QString username, QString password); - /** - * @return the load mechanism to be used - **/ - LoadMechanism::EMechanism getLoadMechanism() const; - void setLoadMechanism(LoadMechanism::EMechanism m); - /** - * @brief activate the load mechanism selected by the user - **/ - void setupLoadMechanism(); +/** + * manages the settings for Mod Organizer. The settings are not cached + * inside the class but read/written directly from/to disc + **/ +class Settings : public QObject +{ + Q_OBJECT; - /** - * @return true if the user configured the use of a network proxy - */ - bool getUseProxy() const; - void setUseProxy(bool b); +public: + Settings(const QString& path); + ~Settings(); - /** - * @return true if endorsement integration is enabled - */ - bool endorsementIntegration() const; - void setEndorsementIntegration(bool b) const; + static Settings &instance(); - EndorsementState endorsementState() const; - void setEndorsementState(EndorsementState s); + QString filename() const; - /** - * @return true if the API counter should be hidden - */ - bool hideAPICounter() const; - void setHideAPICounter(bool b); + std::optional<QVersionNumber> version() const; + void processUpdates(const QVersionNumber& current, const QVersionNumber& last); - /** - * @return true if the user wants to see non-official plugins installed outside MO in his mod list - */ - bool displayForeign() const; - void setDisplayForeign(bool b); + bool firstStart() const; + void setFirstStart(bool b); + + std::vector<std::map<QString, QVariant>> executables() const; + void setExecutables(const std::vector<std::map<QString, QVariant>>& v); + + bool keepBackupOnInstall() const; + void setKeepBackupOnInstall(bool b); + + QString executablesBlacklist() const; + void setExecutablesBlacklist(const QString& s); /** * @brief sets the new motd hash **/ - unsigned int getMotDHash() const; - void setMotDHash(unsigned int hash); + unsigned int motdHash() const; + void setMotdHash(unsigned int hash); /** * @return true if the user wants to have archives being parsed to show conflicts and contents @@ -439,41 +549,45 @@ public: bool archiveParsing() const; void setArchiveParsing(bool b); - /** - * @return short code of the configured language (corresponding to the translation files) - */ - QString language(); - void setLanguage(const QString& name); - - void setDownloadSpeed(const QString &serverName, int bytesPerSecond); - ServerList getServers() const; - ServerList getServersFromOldMap() const; - void updateServers(ServerList servers); - bool usePrereleases() const; void setUsePrereleases(bool b); - /** - * @brief register MO as the handler for nxm links - * @param force set to true to enforce the registration dialog to show up, - * even if the user said earlier not to - */ - void registerAsNXMHandler(bool force); - /** - * @brief color the scrollbar of the mod list for custom separator colors? - * @return the state of the setting - */ - bool colorSeparatorScrollbar() const; - void setColorSeparatorScrollbar(bool b); + GameSettings& game(); + const GameSettings& game() const; + + GeometrySettings& geometry(); + const GeometrySettings& geometry() const; - static QColor getIdealTextColor(const QColor& rBackgroundColor); + WidgetSettings& widgets(); + const WidgetSettings& widgets() const; - MOBase::IPluginGame const *gamePlugin() { return m_GamePlugin; } - const LoadMechanism& loadMechanism() const { return m_LoadMechanism; } + ColorSettings& colors(); + const ColorSettings& colors() const; - QSettings::Status sync() const; + PluginSettings& plugins(); + const PluginSettings& plugins() const; + + PathSettings& paths(); + const PathSettings& paths() const; + + NetworkSettings& network(); + const NetworkSettings& network() const; + + NexusSettings& nexus(); + const NexusSettings& nexus() const; + + SteamSettings& steam(); + const SteamSettings& steam() const; + InterfaceSettings& interface(); + const InterfaceSettings& interface() const; + + DiagnosticsSettings& diagnostics(); + const DiagnosticsSettings& diagnostics() const; + + + QSettings::Status sync() const; void dump() const; public slots: @@ -485,18 +599,19 @@ signals: private: static Settings *s_Instance; - MOBase::IPluginGame const *m_GamePlugin; mutable QSettings m_Settings; + + GameSettings m_Game; GeometrySettings m_Geometry; + WidgetSettings m_Widgets; ColorSettings m_Colors; PluginSettings m_Plugins; - LoadMechanism m_LoadMechanism; - - static bool obfuscate(const QString key, const QString data); - static QString deObfuscate(const QString key); - - QString getConfigurablePath(const QString &key, const QString &def, bool resolve) const; - void setConfigurablePath(const QString &key, const QString& path); + PathSettings m_Paths; + NetworkSettings m_Network; + NexusSettings m_Nexus; + SteamSettings m_Steam; + InterfaceSettings m_Interface; + DiagnosticsSettings m_Diagnostics; }; #endif // SETTINGS_H diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp index 35d14644..1d3d4a39 100644 --- a/src/settingsdialog.cpp +++ b/src/settingsdialog.cpp @@ -51,11 +51,11 @@ int SettingsDialog::exec() { GeometrySaver gs(m_settings, this); - m_settings.restoreIndex(ui->tabWidget); + m_settings.widgets().restoreIndex(ui->tabWidget); auto ret = TutorableDialog::exec(); - m_settings.saveIndex(ui->tabWidget); + m_settings.widgets().saveIndex(ui->tabWidget); if (ret == QDialog::Accepted) { for (auto&& tab : m_tabs) { @@ -109,7 +109,7 @@ void SettingsDialog::accept() if ((QDir::fromNativeSeparators(newModPath) != QDir::fromNativeSeparators( - Settings::instance().getModDirectory(true))) && + Settings::instance().paths().mods(true))) && (QMessageBox::question( nullptr, tr("Confirm"), tr("Changing the mod directory affects all your profiles! " diff --git a/src/settingsdialogdiagnostics.cpp b/src/settingsdialogdiagnostics.cpp index 278da0bf..386c7425 100644 --- a/src/settingsdialogdiagnostics.cpp +++ b/src/settingsdialogdiagnostics.cpp @@ -12,7 +12,7 @@ DiagnosticsSettingsTab::DiagnosticsSettingsTab(Settings& s, SettingsDialog& d) setLevelsBox(); setCrashDumpTypesBox(); - ui->dumpsMaxEdit->setValue(settings().crashDumpsMax()); + ui->dumpsMaxEdit->setValue(settings().diagnostics().crashDumpsMax()); QString logsPath = qApp->property("dataPath").toString() + "/" + QString::fromStdWString(AppConfig::logPath()); @@ -36,7 +36,7 @@ void DiagnosticsSettingsTab::setLevelsBox() ui->logLevelBox->addItem(QObject::tr("Error"), log::Error); for (int i=0; i<ui->logLevelBox->count(); ++i) { - if (ui->logLevelBox->itemData(i) == settings().logLevel()) { + if (ui->logLevelBox->itemData(i) == settings().diagnostics().logLevel()) { ui->logLevelBox->setCurrentIndex(i); break; } @@ -56,7 +56,8 @@ void DiagnosticsSettingsTab::setCrashDumpTypesBox() add(QObject::tr("Data"), CrashDumpsType::Data); add(QObject::tr("Full"), CrashDumpsType::Full); - const auto current = static_cast<int>(settings().crashDumpsType()); + const auto current = static_cast<int>( + settings().diagnostics().crashDumpsType()); for (int i=0; i<ui->dumpsTypeBox->count(); ++i) { if (ui->dumpsTypeBox->itemData(i) == current) { @@ -68,11 +69,11 @@ void DiagnosticsSettingsTab::setCrashDumpTypesBox() void DiagnosticsSettingsTab::update() { - settings().setLogLevel( + settings().diagnostics().setLogLevel( static_cast<log::Levels>(ui->logLevelBox->currentData().toInt())); - settings().setCrashDumpsType( + settings().diagnostics().setCrashDumpsType( static_cast<CrashDumpsType>(ui->dumpsTypeBox->currentData().toInt())); - settings().setCrashDumpsMax(ui->dumpsMaxEdit->value()); + settings().diagnostics().setCrashDumpsMax(ui->dumpsMaxEdit->value()); } diff --git a/src/settingsdialoggeneral.cpp b/src/settingsdialoggeneral.cpp index e3d73037..3f7ece38 100644 --- a/src/settingsdialoggeneral.cpp +++ b/src/settingsdialoggeneral.cpp @@ -11,7 +11,7 @@ GeneralSettingsTab::GeneralSettingsTab(Settings& s, SettingsDialog& d) { addLanguages(); { - QString languageCode = settings().language(); + QString languageCode = settings().interface().language(); int currentID = ui->languageBox->findData(languageCode); // I made a mess. :( Most languages are stored with only the iso country // code (2 characters like "de") but chinese @@ -29,7 +29,7 @@ GeneralSettingsTab::GeneralSettingsTab(Settings& s, SettingsDialog& d) { const int currentID = ui->styleBox->findData( - settings().getStyleName().value_or("")); + settings().interface().styleName().value_or("")); if (currentID != -1) { ui->styleBox->setCurrentIndex(currentID); @@ -51,10 +51,10 @@ GeneralSettingsTab::GeneralSettingsTab(Settings& s, SettingsDialog& d) setContainsColor(settings().colors().modlistContainsPlugin()); setContainedColor(settings().colors().pluginListContained()); - ui->compactBox->setChecked(settings().compactDownloads()); - ui->showMetaBox->setChecked(settings().metaDownloads()); + ui->compactBox->setChecked(settings().interface().compactDownloads()); + ui->showMetaBox->setChecked(settings().interface().metaDownloads()); ui->usePrereleaseBox->setChecked(settings().usePrereleases()); - ui->colorSeparatorsBox->setChecked(settings().colorSeparatorScrollbar()); + ui->colorSeparatorsBox->setChecked(settings().colors().colorSeparatorScrollbar()); QObject::connect(ui->overwritingArchiveBtn, &QPushButton::clicked, [&]{ on_overwritingArchiveBtn_clicked(); }); QObject::connect(ui->overwritingBtn, &QPushButton::clicked, [&]{ on_overwritingBtn_clicked(); }); @@ -69,18 +69,18 @@ GeneralSettingsTab::GeneralSettingsTab(Settings& s, SettingsDialog& d) void GeneralSettingsTab::update() { - const QString oldLanguage = settings().language(); + const QString oldLanguage = settings().interface().language(); const QString newLanguage = ui->languageBox->itemData(ui->languageBox->currentIndex()).toString(); if (newLanguage != oldLanguage) { - settings().setLanguage(newLanguage); + settings().interface().setLanguage(newLanguage); emit settings().languageChanged(newLanguage); } - const QString oldStyle = settings().getStyleName().value_or(""); + const QString oldStyle = settings().interface().styleName().value_or(""); const QString newStyle = ui->styleBox->itemData(ui->styleBox->currentIndex()).toString(); if (oldStyle != newStyle) { - settings().setStyleName(newStyle); + settings().interface().setStyleName(newStyle); emit settings().styleChanged(newStyle); } @@ -91,10 +91,10 @@ void GeneralSettingsTab::update() settings().colors().setModlistContainsPlugin(getContainsColor()); settings().colors().setPluginListContained(getContainedColor()); - settings().setCompactDownloads(ui->compactBox->isChecked()); - settings().setMetaDownloads(ui->showMetaBox->isChecked()); + settings().interface().setCompactDownloads(ui->compactBox->isChecked()); + settings().interface().setMetaDownloads(ui->showMetaBox->isChecked()); settings().setUsePrereleases(ui->usePrereleaseBox->isChecked()); - settings().setColorSeparatorScrollbar(ui->colorSeparatorsBox->isChecked()); + settings().colors().setColorSeparatorScrollbar(ui->colorSeparatorsBox->isChecked()); } void GeneralSettingsTab::addLanguages() @@ -145,7 +145,7 @@ void GeneralSettingsTab::addStyles() void GeneralSettingsTab::resetDialogs() { - settings().resetQuestionButtons(); + settings().widgets().resetQuestionButtons(); } void GeneralSettingsTab::setButtonColor(QPushButton *button, const QColor &color) @@ -161,7 +161,7 @@ void GeneralSettingsTab::setButtonColor(QPushButton *button, const QColor &color .arg(color.green()) .arg(color.blue()) .arg(color.alpha()) - .arg(Settings::getIdealTextColor(color).name()) + .arg(ColorSettings::idealTextColor(color).name()) ); }; diff --git a/src/settingsdialognexus.cpp b/src/settingsdialognexus.cpp index 8822200e..0b08f13f 100644 --- a/src/settingsdialognexus.cpp +++ b/src/settingsdialognexus.cpp @@ -74,13 +74,13 @@ private: NexusSettingsTab::NexusSettingsTab(Settings& s, SettingsDialog& d) : SettingsTab(s, d) { - ui->offlineBox->setChecked(settings().offlineMode()); - ui->proxyBox->setChecked(settings().getUseProxy()); - ui->endorsementBox->setChecked(settings().endorsementIntegration()); - ui->hideAPICounterBox->setChecked(settings().hideAPICounter()); + ui->offlineBox->setChecked(settings().network().offlineMode()); + ui->proxyBox->setChecked(settings().network().useProxy()); + ui->endorsementBox->setChecked(settings().nexus().endorsementIntegration()); + ui->hideAPICounterBox->setChecked(settings().interface().hideAPICounter()); // display server preferences - for (const auto& server : s.getServers()) { + for (const auto& server : s.network().servers()) { QString descriptor = server.name(); if (!descriptor.compare("CDN", Qt::CaseInsensitive)) { @@ -117,12 +117,12 @@ NexusSettingsTab::NexusSettingsTab(Settings& s, SettingsDialog& d) void NexusSettingsTab::update() { - settings().setOfflineMode(ui->offlineBox->isChecked()); - settings().setUseProxy(ui->proxyBox->isChecked()); - settings().setEndorsementIntegration(ui->endorsementBox->isChecked()); - settings().setHideAPICounter(ui->hideAPICounterBox->isChecked()); + settings().network().setOfflineMode(ui->offlineBox->isChecked()); + settings().network().setUseProxy(ui->proxyBox->isChecked()); + settings().nexus().setEndorsementIntegration(ui->endorsementBox->isChecked()); + settings().interface().setHideAPICounter(ui->hideAPICounterBox->isChecked()); - auto servers = settings().getServers(); + auto servers = settings().network().servers(); // store server preference for (int i = 0; i < ui->knownServersList->count(); ++i) { @@ -167,7 +167,7 @@ void NexusSettingsTab::update() } } - settings().updateServers(servers); + settings().network().updateServers(servers); } void NexusSettingsTab::on_nexusConnect_clicked() @@ -225,13 +225,13 @@ void NexusSettingsTab::on_nexusDisconnect_clicked() void NexusSettingsTab::on_clearCacheButton_clicked() { - QDir(Settings::instance().getCacheDirectory()).removeRecursively(); + QDir(Settings::instance().paths().cache()).removeRecursively(); NexusInterface::instance(dialog().m_PluginContainer)->clearCache(); } void NexusSettingsTab::on_associateButton_clicked() { - Settings::instance().registerAsNXMHandler(true); + Settings::instance().nexus().registerAsNXMHandler(true); } void NexusSettingsTab::validateKey(const QString& key) @@ -312,7 +312,7 @@ void NexusSettingsTab::addNexusLog(const QString& s) bool NexusSettingsTab::setKey(const QString& key) { dialog().m_keyChanged = true; - const bool ret = settings().setNexusApiKey(key); + const bool ret = settings().nexus().setApiKey(key); updateNexusState(); return ret; } @@ -320,7 +320,7 @@ bool NexusSettingsTab::setKey(const QString& key) bool NexusSettingsTab::clearKey() { dialog().m_keyChanged = true; - const auto ret = settings().clearNexusApiKey(); + const auto ret = settings().nexus().clearApiKey(); NexusInterface::instance(dialog().m_PluginContainer)->getAccessManager()->clearApiKey(); updateNexusState(); @@ -352,7 +352,7 @@ void NexusSettingsTab::updateNexusButtons() ui->nexusManualKey->setText(QObject::tr("Cancel")); ui->nexusManualKey->setEnabled(true); } - else if (settings().hasNexusApiKey()) { + else if (settings().nexus().hasApiKey()) { // api key is present ui->nexusConnect->setText(QObject::tr("Connect to Nexus")); ui->nexusConnect->setEnabled(false); diff --git a/src/settingsdialogpaths.cpp b/src/settingsdialogpaths.cpp index 32aaf4bf..aeb4dd5d 100644 --- a/src/settingsdialogpaths.cpp +++ b/src/settingsdialogpaths.cpp @@ -6,17 +6,23 @@ PathsSettingsTab::PathsSettingsTab(Settings& s, SettingsDialog& d) : SettingsTab(s, d) { - ui->baseDirEdit->setText(settings().getBaseDirectory()); - ui->managedGameDirEdit->setText(settings().gamePlugin()->gameDirectory().absoluteFilePath(settings().gamePlugin()->binaryName())); - QString basePath = settings().getBaseDirectory(); + ui->baseDirEdit->setText(settings().paths().base()); + + ui->managedGameDirEdit->setText( + settings().game().plugin()->gameDirectory().absoluteFilePath( + settings().game().plugin()->binaryName())); + + QString basePath = settings().paths().base(); QDir baseDir(basePath); + for (const auto &dir : { - std::make_pair(ui->downloadDirEdit, settings().getDownloadDirectory(false)), - std::make_pair(ui->modDirEdit, settings().getModDirectory(false)), - std::make_pair(ui->cacheDirEdit, settings().getCacheDirectory(false)), - std::make_pair(ui->profilesDirEdit, settings().getProfileDirectory(false)), - std::make_pair(ui->overwriteDirEdit, settings().getOverwriteDirectory(false)) + std::make_pair(ui->downloadDirEdit, settings().paths().downloads(false)), + std::make_pair(ui->modDirEdit, settings().paths().mods(false)), + std::make_pair(ui->cacheDirEdit, settings().paths().cache(false)), + std::make_pair(ui->profilesDirEdit, settings().paths().profiles(false)), + std::make_pair(ui->overwriteDirEdit, settings().paths().overwrite(false)) }) { + QString storePath = baseDir.relativeFilePath(dir.second); storePath = dir.second; dir.first->setText(storePath); @@ -40,17 +46,17 @@ PathsSettingsTab::PathsSettingsTab(Settings& s, SettingsDialog& d) void PathsSettingsTab::update() { - using Setter = void (Settings::*)(const QString&); + using Setter = void (PathSettings::*)(const QString&); using Directory = std::tuple<QString, Setter, std::wstring>; - QString basePath = settings().getBaseDirectory(); + QString basePath = settings().paths().base(); for (const Directory &dir :{ - Directory{ui->downloadDirEdit->text(), &Settings::setDownloadDirectory, AppConfig::downloadPath()}, - Directory{ui->cacheDirEdit->text(), &Settings::setCacheDirectory, AppConfig::cachePath()}, - Directory{ui->modDirEdit->text(), &Settings::setModDirectory, AppConfig::modsPath()}, - Directory{ui->overwriteDirEdit->text(), &Settings::setOverwriteDirectory, AppConfig::overwritePath()}, - Directory{ui->profilesDirEdit->text(), &Settings::setProfileDirectory, AppConfig::profilesPath()} + Directory{ui->downloadDirEdit->text(), &PathSettings::setDownloads, AppConfig::downloadPath()}, + Directory{ui->cacheDirEdit->text(), &PathSettings::setCache, AppConfig::cachePath()}, + Directory{ui->modDirEdit->text(), &PathSettings::setMods, AppConfig::modsPath()}, + Directory{ui->overwriteDirEdit->text(), &PathSettings::setOverwrite, AppConfig::overwritePath()}, + Directory{ui->profilesDirEdit->text(), &PathSettings::setProfiles, AppConfig::profilesPath()} }) { QString path; Setter setter; @@ -70,22 +76,26 @@ void PathsSettingsTab::update() } if (QFileInfo(realPath) != QFileInfo(basePath + "/" + QString::fromStdWString(defaultName))) { - (settings().*setter)(path); + (settings().paths().*setter)(path); } else { - (settings().*setter)(""); + (settings().paths().*setter)(""); } } if (QFileInfo(ui->baseDirEdit->text()) != QFileInfo(qApp->property("dataPath").toString())) { - settings().setBaseDirectory(ui->baseDirEdit->text()); + settings().paths().setBase(ui->baseDirEdit->text()); } else { - settings().setBaseDirectory(""); + settings().paths().setBase(""); } - QFileInfo oldGameExe(settings().gamePlugin()->gameDirectory().absoluteFilePath(settings().gamePlugin()->binaryName())); + QFileInfo oldGameExe( + settings().game().plugin()->gameDirectory().absoluteFilePath( + settings().game().plugin()->binaryName())); + QFileInfo newGameExe(ui->managedGameDirEdit->text()); + if (oldGameExe != newGameExe) { - settings().setManagedGameDirectory(newGameExe.absolutePath()); + settings().game().setDirectory(newGameExe.absolutePath()); } } diff --git a/src/settingsdialogsteam.cpp b/src/settingsdialogsteam.cpp index 9ed93e47..3c4c5de6 100644 --- a/src/settingsdialogsteam.cpp +++ b/src/settingsdialogsteam.cpp @@ -5,7 +5,7 @@ SteamSettingsTab::SteamSettingsTab(Settings& s, SettingsDialog& d) : SettingsTab(s, d) { QString username, password; - settings().getSteamLogin(username, password); + settings().steam().login(username, password); ui->steamUserEdit->setText(username); ui->steamPassEdit->setText(password); @@ -13,5 +13,5 @@ SteamSettingsTab::SteamSettingsTab(Settings& s, SettingsDialog& d) void SteamSettingsTab::update() { - settings().setSteamLogin(ui->steamUserEdit->text(), ui->steamPassEdit->text()); + settings().steam().setLogin(ui->steamUserEdit->text(), ui->steamPassEdit->text()); } diff --git a/src/settingsdialogworkarounds.cpp b/src/settingsdialogworkarounds.cpp index b06bd77c..4d811e40 100644 --- a/src/settingsdialogworkarounds.cpp +++ b/src/settingsdialogworkarounds.cpp @@ -6,12 +6,12 @@ WorkaroundsSettingsTab::WorkaroundsSettingsTab(Settings& s, SettingsDialog& d) : SettingsTab(s, d) { - ui->appIDEdit->setText(settings().getSteamAppID()); + ui->appIDEdit->setText(settings().steam().appID()); - LoadMechanism::EMechanism mechanismID = settings().getLoadMechanism(); + LoadMechanism::EMechanism mechanismID = settings().game().loadMechanismType(); int index = 0; - if (settings().loadMechanism().isDirectLoadingSupported()) { + if (settings().game().loadMechanism().isDirectLoadingSupported()) { ui->mechanismBox->addItem(QObject::tr("Mod Organizer"), LoadMechanism::LOAD_MODORGANIZER); if (mechanismID == LoadMechanism::LOAD_MODORGANIZER) { index = ui->mechanismBox->count() - 1; @@ -20,10 +20,10 @@ WorkaroundsSettingsTab::WorkaroundsSettingsTab(Settings& s, SettingsDialog& d) ui->mechanismBox->setCurrentIndex(index); - ui->hideUncheckedBox->setChecked(settings().hideUncheckedPlugins()); - ui->forceEnableBox->setChecked(settings().forceEnableCoreFiles()); - ui->displayForeignBox->setChecked(settings().displayForeign()); - ui->lockGUIBox->setChecked(settings().lockGUI()); + ui->hideUncheckedBox->setChecked(settings().game().hideUncheckedPlugins()); + ui->forceEnableBox->setChecked(settings().game().forceEnableCoreFiles()); + ui->displayForeignBox->setChecked(settings().interface().displayForeign()); + ui->lockGUIBox->setChecked(settings().interface().lockGUI()); ui->enableArchiveParsingBox->setChecked(settings().archiveParsing()); setExecutableBlacklist(settings().executablesBlacklist()); @@ -35,19 +35,19 @@ WorkaroundsSettingsTab::WorkaroundsSettingsTab(Settings& s, SettingsDialog& d) void WorkaroundsSettingsTab::update() { - if (ui->appIDEdit->text() != settings().gamePlugin()->steamAPPId()) { - settings().setSteamAppID(ui->appIDEdit->text()); + if (ui->appIDEdit->text() != settings().game().plugin()->steamAPPId()) { + settings().steam().setAppID(ui->appIDEdit->text()); } else { - settings().setSteamAppID(""); + settings().steam().setAppID(""); } - settings().setLoadMechanism(static_cast<LoadMechanism::EMechanism>( + settings().game().setLoadMechanism(static_cast<LoadMechanism::EMechanism>( ui->mechanismBox->itemData(ui->mechanismBox->currentIndex()).toInt())); - settings().setHideUncheckedPlugins(ui->hideUncheckedBox->isChecked()); - settings().setForceEnableCoreFiles(ui->forceEnableBox->isChecked()); - settings().setDisplayForeign(ui->displayForeignBox->isChecked()); - settings().setLockGUI(ui->lockGUIBox->isChecked()); + settings().game().setHideUncheckedPlugins(ui->hideUncheckedBox->isChecked()); + settings().game().setForceEnableCoreFiles(ui->forceEnableBox->isChecked()); + settings().interface().setDisplayForeign(ui->displayForeignBox->isChecked()); + settings().interface().setLockGUI(ui->lockGUIBox->isChecked()); settings().setArchiveParsing(ui->enableArchiveParsingBox->isChecked()); settings().setExecutablesBlacklist(getExecutableBlacklist()); } diff --git a/src/statusbar.cpp b/src/statusbar.cpp index d22010a5..3734aa87 100644 --- a/src/statusbar.cpp +++ b/src/statusbar.cpp @@ -129,7 +129,7 @@ void StatusBar::setUpdateAvailable(bool b) void StatusBar::checkSettings(const Settings& settings) { - m_api->setVisible(!settings.hideAPICounter()); + m_api->setVisible(!settings.interface().hideAPICounter()); } void StatusBar::showEvent(QShowEvent*) diff --git a/src/usvfsconnector.cpp b/src/usvfsconnector.cpp index 41f58308..4315ed92 100644 --- a/src/usvfsconnector.cpp +++ b/src/usvfsconnector.cpp @@ -163,8 +163,8 @@ QString toString(CrashDumpsType t) UsvfsConnector::UsvfsConnector() { USVFSParameters params; - LogLevel level = toUsvfsLogLevel(Settings::instance().logLevel()); - CrashDumpsType dumpType = Settings::instance().crashDumpsType(); + LogLevel level = toUsvfsLogLevel(Settings::instance().diagnostics().logLevel()); + CrashDumpsType dumpType = Settings::instance().diagnostics().crashDumpsType(); std::string dumpPath = MOShared::ToString(OrganizerCore::crashDumpsPath(), true); USVFSInitParameters(¶ms, SHMID, false, level, dumpType, dumpPath.c_str()); |
