summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/executableslist.cpp9
-rw-r--r--src/executableslist.h5
-rw-r--r--src/filedialogmemory.cpp8
-rw-r--r--src/filedialogmemory.h5
-rw-r--r--src/iuserinterface.h4
-rw-r--r--src/main.cpp96
-rw-r--r--src/mainwindow.cpp116
-rw-r--r--src/mainwindow.h4
-rw-r--r--src/mainwindow.ui5
-rw-r--r--src/organizercore.cpp90
-rw-r--r--src/organizercore.h4
-rw-r--r--src/settings.cpp180
-rw-r--r--src/settings.h55
13 files changed, 359 insertions, 222 deletions
diff --git a/src/executableslist.cpp b/src/executableslist.cpp
index 3f76bb6f..2b3219df 100644
--- a/src/executableslist.cpp
+++ b/src/executableslist.cpp
@@ -21,6 +21,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "iplugingame.h"
#include "utility.h"
+#include "settings.h"
#include <log.h>
#include <QFileInfo>
@@ -64,7 +65,7 @@ bool ExecutablesList::empty() const
return m_Executables.empty();
}
-void ExecutablesList::load(const MOBase::IPluginGame* game, QSettings& settings)
+void ExecutablesList::load(const MOBase::IPluginGame* game, const Settings& s)
{
log::debug("loading executables");
@@ -74,6 +75,8 @@ void ExecutablesList::load(const MOBase::IPluginGame* game, QSettings& settings)
// executables from 2.2.0, see upgradeFromCustom()
bool needsUpgrade = false;
+ auto& settings = const_cast<QSettings&>(s.directInterface());
+
int numCustomExecutables = settings.beginReadArray("customExecutables");
for (int i = 0; i < numCustomExecutables; ++i) {
settings.setArrayIndex(i);
@@ -108,8 +111,10 @@ void ExecutablesList::load(const MOBase::IPluginGame* game, QSettings& settings)
dump();
}
-void ExecutablesList::store(QSettings& settings)
+void ExecutablesList::store(Settings& s)
{
+ auto& settings = s.directInterface();
+
settings.remove("customExecutables");
settings.beginWriteArray("customExecutables");
diff --git a/src/executableslist.h b/src/executableslist.h
index eda2034e..23cf3cfe 100644
--- a/src/executableslist.h
+++ b/src/executableslist.h
@@ -29,6 +29,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QMetaType>
namespace MOBase { class IPluginGame; class ExecutableInfo; }
+class Settings;
/*!
* @brief Information about an executable
@@ -103,7 +104,7 @@ public:
/**
* @brief initializes the list from the settings and the given plugin
**/
- void load(const MOBase::IPluginGame* game, QSettings& settings);
+ void load(const MOBase::IPluginGame* game, const Settings& settings);
/**
* @brief re-adds all the executables from the plugin and renames existing
@@ -114,7 +115,7 @@ public:
/**
* @brief writes the current list to the settings
*/
- void store(QSettings& settings);
+ void store(Settings& settings);
/**
* @brief get an executable by name
diff --git a/src/filedialogmemory.cpp b/src/filedialogmemory.cpp
index 308a175e..48828563 100644
--- a/src/filedialogmemory.cpp
+++ b/src/filedialogmemory.cpp
@@ -27,8 +27,10 @@ FileDialogMemory::FileDialogMemory()
}
-void FileDialogMemory::save(QSettings &settings)
+void FileDialogMemory::save(Settings& s)
{
+ auto& settings = s.directInterface();
+
settings.remove("recentDirectories");
settings.beginWriteArray("recentDirectories");
int index = 0;
@@ -42,8 +44,10 @@ void FileDialogMemory::save(QSettings &settings)
}
-void FileDialogMemory::restore(QSettings &settings)
+void FileDialogMemory::restore(const Settings& s)
{
+ auto& settings = const_cast<QSettings&>(s.directInterface());
+
int size = settings.beginReadArray("recentDirectories");
for (int i = 0; i < size; ++i) {
settings.setArrayIndex(i);
diff --git a/src/filedialogmemory.h b/src/filedialogmemory.h
index 1a72b289..d214a8e6 100644
--- a/src/filedialogmemory.h
+++ b/src/filedialogmemory.h
@@ -23,7 +23,6 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <map>
#include <QString>
-#include <QSettings>
#include <QFileDialog>
class Settings;
@@ -31,8 +30,8 @@ class Settings;
class FileDialogMemory
{
public:
- static void save(QSettings &settings);
- static void restore(QSettings &settings);
+ static void save(Settings& settings);
+ static void restore(const Settings& settings);
static QString getOpenFileName(
const QString &dirID, QWidget *parent = 0, const QString &caption = QString(),
diff --git a/src/iuserinterface.h b/src/iuserinterface.h
index bba8de2b..7205f982 100644
--- a/src/iuserinterface.h
+++ b/src/iuserinterface.h
@@ -10,13 +10,13 @@
#include <QMenu>
-class QSettings;
+class Settings;
class IUserInterface
{
public:
- virtual void storeSettings(QSettings &settings) = 0;
+ virtual void storeSettings(Settings &settings) = 0;
virtual void registerPluginTool(MOBase::IPluginTool *tool, QString name = QString(), QMenu *menu = nullptr) = 0;
virtual void registerPluginTools(std::vector<MOBase::IPluginTool *> toolPlugins) = 0;
diff --git a/src/main.cpp b/src/main.cpp
index 720ecbf9..3e26ea17 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -62,7 +62,6 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QCheckBox>
#include <QDir>
#include <QFileInfo>
-#include <QSettings>
#include <QWhatsThis>
#include <QToolBar>
#include <QFileDialog>
@@ -116,7 +115,7 @@ bool bootstrap()
shellDelete(QStringList(backupDirectory));
}
- // cycle logfile
+ // cycle log file
removeOldFiles(qApp->property("dataPath").toString() + "/" + QString::fromStdWString(AppConfig::logPath()),
"usvfs*.log", 5, QDir::Name);
@@ -247,7 +246,7 @@ static bool HaveWriteAccess(const std::wstring &path)
QString determineProfile(QStringList &arguments, const Settings &settings)
{
- QString selectedProfileName = settings.getSelectedProfileName();
+ auto selectedProfileName = settings.getSelectedProfileName();
{ // see if there is a profile on the command line
int profileIndex = arguments.indexOf("-p", 1);
@@ -259,14 +258,14 @@ QString determineProfile(QStringList &arguments, const Settings &settings)
arguments.removeAt(profileIndex);
}
- if (selectedProfileName.isEmpty()) {
+ if (!selectedProfileName) {
log::debug("no configured profile");
selectedProfileName = "Default";
} else {
- log::debug("configured profile: {}", selectedProfileName);
+ log::debug("configured profile: {}", *selectedProfileName);
}
- return selectedProfileName;
+ return *selectedProfileName;
}
MOBase::IPluginGame *selectGame(
@@ -290,27 +289,27 @@ MOBase::IPluginGame *determineCurrentGame(
//user has done something odd.
//If the game name has been set up, try to use that.
- const QString gameName = settings.getManagedGameName();
- bool gameConfigured = !gameName.isEmpty();
+ const auto gameName = settings.getManagedGameName();
+ const bool gameConfigured = (gameName.has_value() && *gameName != "");
if (gameConfigured) {
- MOBase::IPluginGame *game = plugins.managedGame(gameName);
+ MOBase::IPluginGame *game = plugins.managedGame(*gameName);
if (game == nullptr) {
- reportError(QObject::tr("Plugin to handle %1 no longer installed").arg(gameName));
+ reportError(QObject::tr("Plugin to handle %1 no longer installed").arg(*gameName));
return nullptr;
}
- QString gamePath = settings.getManagedGameDirectory();
- if (gamePath == "") {
+ auto gamePath = settings.getManagedGameDirectory();
+ if (!gamePath || *gamePath == "") {
gamePath = game->gameDirectory().absolutePath();
}
- QDir gameDir(gamePath);
+ QDir gameDir(*gamePath);
QFileInfo directoryInfo(gameDir.path());
if (directoryInfo.isSymLink()) {
reportError(QObject::tr("The configured path to the game directory (%1) appears to be a symbolic (or other) link. "
- "This setup is incompatible with MO2's VFS and will not run correctly.").arg(gamePath));
+ "This setup is incompatible with MO2's VFS and will not run correctly.").arg(*gamePath));
}
if (game->looksValid(gameDir)) {
@@ -321,17 +320,20 @@ 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 QString gamePath = settings.getManagedGameDirectory();
- reportError(QObject::tr("Could not use configuration settings for game \"%1\", path \"%2\".").
- arg(gameName).arg(gamePath));
+ const auto gamePath = settings.getManagedGameDirectory();
+
+ reportError(
+ QObject::tr("Could not use configuration settings for game \"%1\", path \"%2\".")
+ .arg(*gameName).arg(gamePath ? *gamePath : ""));
}
- SelectionDialog selection(gameConfigured ? QObject::tr("Please select the installation of %1 to manage").arg(gameName)
- : QObject::tr("Please select the game to manage"), nullptr, QSize(32, 32));
+ SelectionDialog selection(gameConfigured ?
+ QObject::tr("Please select the installation of %1 to manage").arg(*gameName) :
+ QObject::tr("Please select the game to manage"), nullptr, QSize(32, 32));
for (IPluginGame *game : plugins.plugins<IPluginGame>()) {
//If a game is already configured, skip any plugins that are not for that game
- if (gameConfigured && gameName.compare(game->gameName(), Qt::CaseInsensitive) != 0)
+ if (gameConfigured && gameName->compare(game->gameName(), Qt::CaseInsensitive) != 0)
continue;
//Only add games that are installed
@@ -355,9 +357,11 @@ MOBase::IPluginGame *determineCurrentGame(
return selectGame(settings, game->gameDirectory(), game);
}
- gamePath = QFileDialog::getExistingDirectory(nullptr, gameConfigured ? QObject::tr("Please select the installation of %1 to manage").arg(gameName)
- : QObject::tr("Please select the game to manage"),
- QString(), QFileDialog::ShowDirsOnly);
+ gamePath = QFileDialog::getExistingDirectory(nullptr, gameConfigured ?
+ QObject::tr("Please select the installation of %1 to manage").arg(*gameName) :
+ QObject::tr("Please select the game to manage"),
+ QString(), QFileDialog::ShowDirsOnly);
+
if (!gamePath.isEmpty()) {
QDir gameDir(gamePath);
QFileInfo directoryInfo(gamePath);
@@ -368,7 +372,7 @@ MOBase::IPluginGame *determineCurrentGame(
QList<IPluginGame *> possibleGames;
for (IPluginGame * const game : plugins.plugins<IPluginGame>()) {
//If a game is already configured, skip any plugins that are not for that game
- if (gameConfigured && gameName.compare(game->gameName(), Qt::CaseInsensitive) != 0)
+ if (gameConfigured && gameName->compare(game->gameName(), Qt::CaseInsensitive) != 0)
continue;
//Only try plugins that look valid for this directory
@@ -376,24 +380,31 @@ MOBase::IPluginGame *determineCurrentGame(
possibleGames.append(game);
}
}
+
if (possibleGames.count() > 1) {
- SelectionDialog browseSelection(gameConfigured ? QObject::tr("Please select the installation of %1 to manage").arg(gameName)
- : QObject::tr("Please select the game to manage"),
- nullptr, QSize(32, 32));
+ SelectionDialog browseSelection(gameConfigured ?
+ QObject::tr("Please select the installation of %1 to manage").arg(*gameName) :
+ QObject::tr("Please select the game to manage"),
+ nullptr, QSize(32, 32));
+
for (IPluginGame *game : possibleGames) {
browseSelection.addChoice(game->gameIcon(), game->gameName(), gamePath, QVariant::fromValue(game));
}
+
if (browseSelection.exec() == QDialog::Accepted) {
return selectGame(settings, gameDir, browseSelection.getChoiceData().value<IPluginGame *>());
} else {
- reportError(gameConfigured ? QObject::tr("Canceled finding %1 in \"%2\".").arg(gameName).arg(gamePath)
- : QObject::tr("Canceled finding game in \"%1\".").arg(gamePath));
+ reportError(gameConfigured ?
+ QObject::tr("Canceled finding %1 in \"%2\".").arg(*gameName).arg(gamePath) :
+ QObject::tr("Canceled finding game in \"%1\".").arg(gamePath));
}
} else if(possibleGames.count() == 1) {
return selectGame(settings, gameDir, possibleGames[0]);
} else {
if (gameConfigured) {
- reportError(QObject::tr("%1 not identified in \"%2\". The directory is required to contain the game binary.").arg(gameName).arg(gamePath));
+ reportError(
+ QObject::tr("%1 not identified in \"%2\". The directory is required to contain the game binary.")
+ .arg(*gameName).arg(gamePath));
} else {
QString supportedGames;
@@ -608,7 +619,11 @@ int runApplication(MOApplication &application, SingleInstance &instance,
organizer.setManagedGame(game);
organizer.createDefaultProfile();
- if (settings.getManagedGameEdition() == "") {
+ QString edition;
+
+ if (auto v=settings.getManagedGameEdition()) {
+ edition = *v;
+ } else {
QStringList editions = game->gameVariants();
if (editions.size() > 1) {
SelectionDialog selection(
@@ -624,12 +639,15 @@ int runApplication(MOApplication &application, SingleInstance &instance,
if (selection.exec() == QDialog::Rejected) {
return 1;
} else {
- settings.setManagedGameEdition(selection.getChoiceString());
+ edition = selection.getChoiceString();
+ settings.setManagedGameEdition(edition);
}
}
}
- game->setGameVariant(settings.getManagedGameEdition());
+ Q_ASSERT(!edition.isEmpty());
+
+ game->setGameVariant(edition);
log::info("managing game at {}", game->gameDirectory().absolutePath());
@@ -679,10 +697,10 @@ int runApplication(MOApplication &application, SingleInstance &instance,
QPixmap pixmap(splashPath);
QSplashScreen splash(pixmap);
- const int monitor = settings.getMainWindowMonitor();
- if (monitor != -1 && QGuiApplication::screens().size() > monitor) {
- QGuiApplication::screens().at(monitor)->geometry().center();
- const QPoint center = QGuiApplication::screens().at(monitor)->geometry().center();
+ const auto monitor = settings.geometry().getMainWindowMonitor();
+ if (monitor && QGuiApplication::screens().size() > *monitor) {
+ QGuiApplication::screens().at(*monitor)->geometry().center();
+ const QPoint center = QGuiApplication::screens().at(*monitor)->geometry().center();
splash.move(center - splash.rect().center());
} else {
const QPoint center = QGuiApplication::primaryScreen()->geometry().center();
@@ -703,7 +721,7 @@ int runApplication(MOApplication &application, SingleInstance &instance,
+ QString::fromStdWString(AppConfig::tutorialsPath()) + "/",
&organizer);
- if (!application.setStyleFile(settings.getStyleName())) {
+ if (!application.setStyleFile(settings.getStyleName().value_or(""))) {
// disable invalid stylesheet
settings.setStyleName("");
}
@@ -726,7 +744,7 @@ int runApplication(MOApplication &application, SingleInstance &instance,
// this must be before readSettings(), see DockFixer in mainwindow.cpp
splash.finish(&mainWindow);
- mainWindow.readSettings();
+ mainWindow.readSettings(settings);
log::debug("displaying main window");
mainWindow.show();
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index 7f7ded80..e77d08b1 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -216,26 +216,24 @@ const QSize LargeToolbarSize(42, 36);
class DockFixer
{
public:
- static void save(MainWindow* mw, QSettings& settings)
+ static void save(MainWindow* mw, Settings& settings)
{
- const auto docks = mw->findChildren<QDockWidget*>();
-
// saves the size of each dock
- for (int i=0; i<docks.size(); ++i) {
+ for (const auto* dock : mw->findChildren<QDockWidget*>()) {
int size = 0;
// save the width for horizontal docks, or the height for vertical
- if (orientation(mw, docks[i]) == Qt::Horizontal) {
- size = docks[i]->size().width();
+ if (orientation(mw, dock) == Qt::Horizontal) {
+ size = dock->size().width();
} else {
- size = docks[i]->size().height();
+ size = dock->size().height();
}
- settings.setValue(settingName(docks[i]), size);
+ settings.geometry().setDockSize(dock->objectName(), size);
}
}
- static void restore(MainWindow* mw, const QSettings& settings)
+ static void restore(MainWindow* mw, const Settings& settings)
{
struct DockInfo
{
@@ -246,16 +244,11 @@ public:
std::vector<DockInfo> dockInfos;
- const auto docks = mw->findChildren<QDockWidget*>();
-
// for each dock
- for (int i=0; i<docks.size(); ++i) {
- const QString name = settingName(docks[i]);
-
- if (settings.contains(name)) {
+ for (auto* dock : mw->findChildren<QDockWidget*>()) {
+ if (auto size=settings.geometry().getDockSize(dock->objectName())) {
// remember this dock, its size and orientation
- const auto size = settings.value(name).toInt();
- dockInfos.push_back({docks[i], size, orientation(mw, docks[i])});
+ dockInfos.push_back({dock, *size, orientation(mw, dock)});
}
}
@@ -264,30 +257,25 @@ public:
//
// some people said a single processEvents() call is enough, but it doesn't
// look like it
- QTimer::singleShot(1, [=] {
+ QTimer::singleShot(5, [=] {
for (const auto& info : dockInfos) {
mw->resizeDocks({info.d}, {info.size}, info.ori);
}
- });
+ });
}
- static Qt::Orientation orientation(QMainWindow* mw, QDockWidget* d)
+ static Qt::Orientation orientation(QMainWindow* mw, const QDockWidget* d)
{
// docks in these areas are horizontal
const auto horizontalAreas =
Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea;
- if (mw->dockWidgetArea(d) & horizontalAreas) {
+ if (mw->dockWidgetArea(const_cast<QDockWidget*>(d)) & horizontalAreas) {
return Qt::Horizontal;
} else {
return Qt::Vertical;
}
}
-
- static QString settingName(QDockWidget* d)
- {
- return "geometry/" + d->objectName() + "_size";
- }
};
@@ -359,9 +347,6 @@ MainWindow::MainWindow(Settings &settings
ui->logList->setCore(m_OrganizerCore);
- int splitterSize = this->size().height(); // actually total window size, but the splitter doesn't seem to return the true value
- ui->topLevelSplitter->setSizes(QList<int>() << splitterSize - 100 << 100);
-
updateProblemsButton();
setupToolbar();
@@ -540,8 +525,7 @@ MainWindow::MainWindow(Settings &settings
connect(&m_SaveMetaTimer, SIGNAL(timeout()), this, SLOT(saveModMetas()));
m_SaveMetaTimer.start(5000);
- setCategoryListVisible(settings.isCategoryListVisible());
- FileDialogMemory::restore(settings.directInterface());
+ FileDialogMemory::restore(settings);
fixCategories();
@@ -2247,52 +2231,50 @@ void MainWindow::activateProxy(bool activate)
busyDialog.hide();
}
-void MainWindow::readSettings()
+void MainWindow::readSettings(const Settings& settings)
{
- QSettings settings(qApp->property("dataPath").toString() + "/" + QString::fromStdWString(AppConfig::iniFileName()), QSettings::IniFormat);
-
- if (settings.contains("window_geometry")) {
- restoreGeometry(settings.value("window_geometry").toByteArray());
+ if (auto v=settings.geometry().getMainWindow()) {
+ restoreGeometry(*v);
}
- if (settings.contains("window_state")) {
- restoreState(settings.value("window_state").toByteArray());
+ if (auto v=settings.geometry().getMainWindowState()) {
+ restoreState(*v);
}
- if (settings.contains("toolbar_size")) {
- setToolbarSize(settings.value("toolbar_size").toSize());
+ if (auto v=settings.geometry().getToolbarSize()) {
+ setToolbarSize(*v);
}
- if (settings.contains("toolbar_button_style")) {
- setToolbarButtonStyle(static_cast<Qt::ToolButtonStyle>(
- settings.value("toolbar_button_style").toInt()));
+ if (auto v=settings.geometry().getToolbarButtonStyle()) {
+ setToolbarButtonStyle(*v);
}
- if (settings.contains("menubar_visible")) {
- showMenuBar(settings.value("menubar_visible").toBool());
+ if (auto v=settings.geometry().getMenubarVisible()) {
+ showMenuBar(*v);
}
- if (settings.contains("statusbar_visible")) {
- showStatusBar(settings.value("statusbar_visible").toBool());
+ if (auto v=settings.geometry().getStatusbarVisible()) {
+ showStatusBar(*v);
}
- if (settings.contains("window_split")) {
- ui->splitter->restoreState(settings.value("window_split").toByteArray());
+ if (auto v=settings.geometry().getMainSplitterState()) {
+ ui->splitter->restoreState(*v);
}
- if (settings.contains("log_split")) {
- ui->topLevelSplitter->restoreState(settings.value("log_split").toByteArray());
+ {
+ auto v = settings.geometry().getFiltersVisible().value_or(false);
+ setCategoryListVisible(v);
+ ui->displayCategoriesBtn->setChecked(v);
}
- bool filtersVisible = settings.value("filters_visible", false).toBool();
- setCategoryListVisible(filtersVisible);
- ui->displayCategoriesBtn->setChecked(filtersVisible);
-
- int selectedExecutable = settings.value("selected_executable").toInt();
- setExecutableIndex(selectedExecutable);
+ if (auto v=settings.getSelectedExecutable()) {
+ setExecutableIndex(*v);
+ }
- if (settings.value("Settings/use_proxy", false).toBool()) {
- activateProxy(true);
+ if (auto v=settings.getUseProxy()) {
+ if (*v) {
+ activateProxy(true);
+ }
}
DockFixer::restore(this, settings);
@@ -2335,6 +2317,12 @@ void MainWindow::processUpdates() {
ui->downloadView->header()->hideSection(i);
}
}
+ if (lastVersion < QVersionNumber(2, 2, 2)) {
+ QSettings &instance = Settings::instance().directInterface();
+
+ // log splitter is gone, it's a dock now
+ instance.remove("log_split");
+ }
}
if (currentVersion > lastVersion) {
@@ -2354,7 +2342,9 @@ void MainWindow::processUpdates() {
settings.setValue("version", currentVersion.toString());
}
-void MainWindow::storeSettings(QSettings &settings) {
+void MainWindow::storeSettings(Settings& s) {
+ auto& settings = s.directInterface();
+
settings.setValue("group_state", ui->groupCombo->currentIndex());
settings.setValue("selected_executable",
ui->executablesListBox->currentIndex());
@@ -2367,7 +2357,6 @@ void MainWindow::storeSettings(QSettings &settings) {
settings.remove("menubar_visible");
settings.remove("window_split");
settings.remove("window_monitor");
- settings.remove("log_split");
settings.remove("filters_visible");
settings.remove("browser_geometry");
settings.remove("geometry");
@@ -2383,7 +2372,6 @@ void MainWindow::storeSettings(QSettings &settings) {
QScreen *screen = this->window()->windowHandle()->screen();
int screenId = QGuiApplication::screens().indexOf(screen);
settings.setValue("window_monitor", screenId);
- settings.setValue("log_split", ui->topLevelSplitter->saveState());
settings.setValue("browser_geometry", m_IntegratedBrowser.saveGeometry());
settings.setValue("filters_visible", ui->displayCategoriesBtn->isChecked());
@@ -2392,7 +2380,7 @@ void MainWindow::storeSettings(QSettings &settings) {
settings.setValue(key, kv.second->saveState());
}
- DockFixer::save(this, settings);
+ DockFixer::save(this, s);
}
}
@@ -5213,7 +5201,7 @@ void MainWindow::on_actionSettings_triggered()
QString oldModDirectory(settings.getModDirectory());
QString oldCacheDirectory(settings.getCacheDirectory());
QString oldProfilesDirectory(settings.getProfileDirectory());
- QString oldManagedGameDirectory(settings.getManagedGameDirectory());
+ QString oldManagedGameDirectory(settings.getManagedGameDirectory().value_or(""));
bool oldDisplayForeign(settings.displayForeign());
bool proxy = settings.useProxy();
DownloadManager *dlManager = m_OrganizerCore.downloadManager();
diff --git a/src/mainwindow.h b/src/mainwindow.h
index 7326425a..d4513c0f 100644
--- a/src/mainwindow.h
+++ b/src/mainwindow.h
@@ -119,8 +119,8 @@ public:
QWidget *parent = 0);
~MainWindow();
- void storeSettings(QSettings &settings) override;
- void readSettings();
+ void storeSettings(Settings& settings) override;
+ void readSettings(const Settings& settings);
void processUpdates();
virtual ILockedWaitingForProcess* lock() override;
diff --git a/src/mainwindow.ui b/src/mainwindow.ui
index 6c6d0bca..e9910b83 100644
--- a/src/mainwindow.ui
+++ b/src/mainwindow.ui
@@ -47,10 +47,6 @@
<number>0</number>
</property>
<item>
- <widget class="QSplitter" name="topLevelSplitter">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
<widget class="QWidget" name="horizontalLayoutWidget_2">
<layout class="QHBoxLayout" name="horizontalLayout_10" stretch="0,2">
<item>
@@ -1286,7 +1282,6 @@ p, li { white-space: pre-wrap; }
</item>
</layout>
</widget>
- </widget>
</item>
</layout>
</widget>
diff --git a/src/organizercore.cpp b/src/organizercore.cpp
index 72c8dab5..a64d93b4 100644
--- a/src/organizercore.cpp
+++ b/src/organizercore.cpp
@@ -94,15 +94,6 @@ static bool isOnline()
return false;
}
-static bool renameFile(const QString &oldName, const QString &newName,
- bool overwrite = true)
-{
- if (overwrite && QFile::exists(newName)) {
- QFile::remove(newName);
- }
- return QFile::rename(oldName, newName);
-}
-
static std::wstring getProcessName(HANDLE process)
{
wchar_t buffer[MAX_PATH];
@@ -342,80 +333,37 @@ OrganizerCore::~OrganizerCore()
delete m_DirectoryStructure;
}
-QString OrganizerCore::commitSettings(const QString &iniFile)
-{
- if (!shellRename(iniFile + ".new", iniFile, true, qApp->activeWindow())) {
- DWORD err = ::GetLastError();
- // make a second attempt using qt functions but if that fails print the
- // error from the first attempt
- if (!renameFile(iniFile + ".new", iniFile)) {
- return QString::fromStdWString(formatSystemMessage(err));
- }
- }
- return QString();
-}
-
-QSettings::Status OrganizerCore::storeSettings(const QString &fileName)
+void OrganizerCore::storeSettings()
{
- QSettings settings(fileName, QSettings::IniFormat);
-
if (m_UserInterface != nullptr) {
- m_UserInterface->storeSettings(settings);
+ m_UserInterface->storeSettings(m_Settings);
}
if (m_CurrentProfile != nullptr) {
- settings.setValue("selected_profile",
- m_CurrentProfile->name().toUtf8().constData());
+ m_Settings.setSelectedProfileName(m_CurrentProfile->name());
}
- m_ExecutablesList.store(settings);
-
- FileDialogMemory::save(settings);
+ m_ExecutablesList.store(m_Settings);
- settings.sync();
- return settings.status();
-}
-
-void OrganizerCore::storeSettings()
-{
- QString iniFile = qApp->property("dataPath").toString() + "/"
- + QString::fromStdWString(AppConfig::iniFileName());
- if (QFileInfo(iniFile).exists()) {
- if (!shellCopy(iniFile, iniFile + ".new", true, qApp->activeWindow())) {
- const auto e = GetLastError();
- QMessageBox::critical(
- qApp->activeWindow(), tr("Failed to write settings"),
- tr("An error occurred trying to update MO settings to %1: %2")
- .arg(iniFile)
- .arg(QString::fromStdWString(formatSystemMessage(e))));
- return;
- }
- }
+ FileDialogMemory::save(m_Settings);
- QString writeTarget = iniFile + ".new";
+ const auto result = m_Settings.sync();
- QSettings::Status result = storeSettings(writeTarget);
+ if (result != QSettings::NoError) {
+ QString reason;
- if (result == QSettings::NoError) {
- QString errMsg = commitSettings(iniFile);
- if (!errMsg.isEmpty()) {
- log::warn(
- "settings file not writable, may be locked by another "
- "application, trying direct write");
- writeTarget = iniFile;
- result = storeSettings(iniFile);
+ if (result == QSettings::AccessError) {
+ reason = tr("File is write protected");
+ } else if (result == QSettings::FormatError) {
+ reason = tr("Invalid file format (probably a bug)");
+ } else {
+ reason = tr("Unknown error %1").arg(result);
}
- }
- if (result != QSettings::NoError) {
- QString reason = result == QSettings::AccessError
- ? tr("File is write protected")
- : result == QSettings::FormatError
- ? tr("Invalid file format (probably a bug)")
- : tr("Unknown error %1").arg(result);
+
QMessageBox::critical(
- qApp->activeWindow(), tr("Failed to write settings"),
- tr("An error occurred trying to write back MO settings to %1: %2")
- .arg(writeTarget, reason));
+ 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));
}
}
@@ -487,7 +435,7 @@ void OrganizerCore::updateExecutablesList()
return;
}
- m_ExecutablesList.load(managedGame(), m_Settings.directInterface());
+ m_ExecutablesList.load(managedGame(), m_Settings);
// TODO this has nothing to do with executables list move to an appropriate
// function!
diff --git a/src/organizercore.h b/src/organizercore.h
index 926a21f0..4bcfe745 100644
--- a/src/organizercore.h
+++ b/src/organizercore.h
@@ -288,10 +288,6 @@ private:
void storeSettings();
- QSettings::Status storeSettings(const QString &fileName);
-
- QString commitSettings(const QString &iniFile);
-
bool queryApi(QString &apiKey);
void updateModActiveState(int index, bool active);
diff --git a/src/settings.cpp b/src/settings.cpp
index 5d103267..d843a0db 100644
--- a/src/settings.cpp
+++ b/src/settings.cpp
@@ -26,10 +26,56 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
using namespace MOBase;
+template <class T>
+T convertVariant(const QVariant& v);
+
+template <>
+QByteArray convertVariant<QByteArray>(const QVariant& v)
+{
+ return v.toByteArray();
+}
+
+template <>
+QString convertVariant<QString>(const QVariant& v)
+{
+ return v.toString();
+}
+
+template <>
+int convertVariant<int>(const QVariant& v)
+{
+ return v.toInt();
+}
+
+template <>
+bool convertVariant<bool>(const QVariant& v)
+{
+ return v.toBool();
+}
+
+template <>
+QSize convertVariant<QSize>(const QVariant& v)
+{
+ return v.toSize();
+}
+
+
+
+template <class T>
+std::optional<T> getOptional(const QSettings& s, const QString& name)
+{
+ if (s.contains(name)) {
+ return convertVariant<T>(s.value(name));
+ }
+
+ return {};
+}
+
+
Settings *Settings::s_Instance = nullptr;
Settings::Settings(const QString& path)
- : m_Settings(path, QSettings::IniFormat)
+ : m_Settings(path, QSettings::IniFormat), m_Geometry(m_Settings)
{
if (s_Instance != nullptr) {
throw std::runtime_error("second instance of \"Settings\" created");
@@ -51,6 +97,11 @@ Settings &Settings::instance()
return *s_Instance;
}
+QString Settings::getFilename() const
+{
+ return m_Settings.fileName();
+}
+
void Settings::clearPlugins()
{
m_Plugins.clear();
@@ -278,9 +329,13 @@ QString Settings::getModDirectory(bool resolve) const
return getConfigurablePath("mod_directory", ToQString(AppConfig::modsPath()), resolve);
}
-QString Settings::getManagedGameDirectory() const
+std::optional<QString> Settings::getManagedGameDirectory() const
{
- return QString::fromUtf8(m_Settings.value("gamePath", "").toByteArray());
+ if (auto v=getOptional<QByteArray>(m_Settings, "gamePath")) {
+ return QString::fromUtf8(*v);
+ }
+
+ return {};
}
void Settings::setManagedGameDirectory(const QString& path)
@@ -288,9 +343,9 @@ void Settings::setManagedGameDirectory(const QString& path)
m_Settings.setValue("gamePath", QDir::toNativeSeparators(path).toUtf8());
}
-QString Settings::getManagedGameName() const
+std::optional<QString> Settings::getManagedGameName() const
{
- return m_Settings.value("gameName", "").toString();
+ return getOptional<QString>(m_Settings, "gameName");
}
void Settings::setManagedGameName(const QString& name)
@@ -298,9 +353,9 @@ void Settings::setManagedGameName(const QString& name)
m_Settings.setValue("gameName", name);
}
-QString Settings::getManagedGameEdition() const
+std::optional<QString> Settings::getManagedGameEdition() const
{
- return m_Settings.value("game_edition", "").toString();
+ return getOptional<QString>(m_Settings, "game_edition");
}
void Settings::setManagedGameEdition(const QString& name)
@@ -308,19 +363,23 @@ void Settings::setManagedGameEdition(const QString& name)
m_Settings.setValue("game_edition", name);
}
-QString Settings::getSelectedProfileName() const
+std::optional<QString> Settings::getSelectedProfileName() const
{
- return QString::fromUtf8(m_Settings.value("selected_profile", "").toByteArray());
+ if (auto v=getOptional<QByteArray>(m_Settings, "selected_profile")) {
+ return QString::fromUtf8(*v);
+ }
+
+ return {};
}
-int Settings::getMainWindowMonitor() const
+void Settings::setSelectedProfileName(const QString& name)
{
- return m_Settings.value("window_monitor", -1).toInt();
+ m_Settings.setValue("selected_profile", name.toUtf8());
}
-QString Settings::getStyleName() const
+std::optional<QString> Settings::getStyleName() const
{
- return m_Settings.value("Settings/style", "").toString();
+ return getOptional<QString>(m_Settings, "Settings/style");
}
void Settings::setStyleName(const QString& name)
@@ -328,9 +387,14 @@ void Settings::setStyleName(const QString& name)
m_Settings.setValue("Settings/style", name);
}
-bool Settings::isCategoryListVisible() const
+std::optional<int> Settings::getSelectedExecutable() const
{
- return m_Settings.value("categorylist_visible", true).toBool();
+ return getOptional<int>(m_Settings, "selected_executable");
+}
+
+std::optional<bool> Settings::getUseProxy() const
+{
+ return getOptional<bool>(m_Settings, "Settings/use_proxy");
}
QString Settings::getProfileDirectory(bool resolve) const
@@ -659,6 +723,22 @@ void Settings::writePluginBlacklist()
m_Settings.endArray();
}
+GeometrySettings& Settings::geometry()
+{
+ return m_Geometry;
+}
+
+const GeometrySettings& Settings::geometry() const
+{
+ return m_Geometry;
+}
+
+QSettings::Status Settings::sync() const
+{
+ m_Settings.sync();
+ return m_Settings.status();
+}
+
void Settings::dump() const
{
static const QStringList ignore({
@@ -679,3 +759,73 @@ void Settings::dump() const
m_Settings.endGroup();
}
+
+
+GeometrySettings::GeometrySettings(QSettings& s)
+ : m_Settings(s)
+{
+}
+
+std::optional<QByteArray> GeometrySettings::getMainWindow() const
+{
+ return getOptional<QByteArray>(m_Settings, "window_geometry");
+}
+
+std::optional<QByteArray> GeometrySettings::getMainWindowState() const
+{
+ return getOptional<QByteArray>(m_Settings, "window_state");
+}
+
+std::optional<QSize> GeometrySettings::getToolbarSize() const
+{
+ return getOptional<QSize>(m_Settings, "toolbar_size");
+}
+
+std::optional<Qt::ToolButtonStyle> GeometrySettings::getToolbarButtonStyle() const
+{
+ if (auto v=getOptional<int>(m_Settings, "toolbar_button_style")) {
+ return static_cast<Qt::ToolButtonStyle>(*v);
+ }
+
+ return {};
+}
+
+std::optional<bool> GeometrySettings::getMenubarVisible() const
+{
+ return getOptional<bool>(m_Settings, "menubar_visible");
+}
+
+std::optional<bool> GeometrySettings::getStatusbarVisible() const
+{
+ return getOptional<bool>(m_Settings, "statusbar_visible");
+}
+
+std::optional<QByteArray> GeometrySettings::getMainSplitterState() const
+{
+ return getOptional<QByteArray>(m_Settings, "window_split");
+}
+
+std::optional<bool> GeometrySettings::getFiltersVisible() const
+{
+ return getOptional<bool>(m_Settings, "filters_visible");
+}
+
+std::optional<int> GeometrySettings::getMainWindowMonitor() const
+{
+ return getOptional<int>(m_Settings, "window_monitor");
+}
+
+void GeometrySettings::setDockSize(const QString& name, int size)
+{
+ m_Settings.setValue("geometry/" + name + "_size", size);
+}
+
+std::optional<int> GeometrySettings::getDockSize(const QString& name) const
+{
+ return getOptional<int>(m_Settings, "geometry/" + name + "_size");
+}
+
+std::optional<bool> GeometrySettings::isCategoryListVisible() const
+{
+ return getOptional<bool>(m_Settings, "categorylist_visible");
+}
diff --git a/src/settings.h b/src/settings.h
index f06aece9..066843c2 100644
--- a/src/settings.h
+++ b/src/settings.h
@@ -31,13 +31,40 @@ namespace MOBase {
class PluginContainer;
struct ServerInfo;
+
+class GeometrySettings
+{
+public:
+ GeometrySettings(QSettings& s);
+
+ std::optional<QByteArray> getMainWindow() const;
+ std::optional<QByteArray> getMainWindowState() const;
+ std::optional<QSize> getToolbarSize() const;
+ std::optional<Qt::ToolButtonStyle> getToolbarButtonStyle() const;
+ std::optional<bool> getMenubarVisible() const;
+ std::optional<bool> getStatusbarVisible() const;
+ std::optional<QByteArray> getMainSplitterState() const;
+ std::optional<bool> getFiltersVisible() const;
+
+ std::optional<int> getMainWindowMonitor() const;
+ void setDockSize(const QString& name, int size);
+
+ std::optional<int> getDockSize(const QString& name) const;
+
+ std::optional<bool> isCategoryListVisible() const;
+
+private:
+ QSettings& m_Settings;
+};
+
+
/**
* 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
+ Q_OBJECT;
public:
Settings(const QString& path);
@@ -45,6 +72,8 @@ public:
static Settings &instance();
+ QString getFilename() const;
+
/**
* unregister all plugins from settings
*/
@@ -122,25 +151,26 @@ public:
/**
* retrieve the directory where the managed game is stored (with native separators)
**/
- QString getManagedGameDirectory() const;
+ std::optional<QString> getManagedGameDirectory() const;
void setManagedGameDirectory(const QString& path);
- QString getManagedGameName() const;
+ std::optional<QString> getManagedGameName() const;
void setManagedGameName(const QString& name);
- QString getManagedGameEdition() const;
+ std::optional<QString> getManagedGameEdition() const;
void setManagedGameEdition(const QString& name);
- QString getSelectedProfileName() const;
-
- // returns -1 if not set
- //
- int getMainWindowMonitor() const;
+ std::optional<QString> getSelectedProfileName() const;
+ void setSelectedProfileName(const QString& name);
- QString getStyleName() const;
+ std::optional<QString> getStyleName() const;
void setStyleName(const QString& name);
- bool isCategoryListVisible() const;
+ std::optional<int> getSelectedExecutable() const;
+ std::optional<bool> getUseProxy() const;
+
+ GeometrySettings& geometry();
+ const GeometrySettings& geometry() const;
/**
* retrieve the directory where profiles stored (with native separators)
@@ -388,6 +418,8 @@ public:
MOBase::IPluginGame const *gamePlugin() { return m_GamePlugin; }
const LoadMechanism& loadMechanism() const { return m_LoadMechanism; }
+ QSettings::Status sync() const;
+
void dump() const;
// temp
@@ -407,6 +439,7 @@ private:
static Settings *s_Instance;
MOBase::IPluginGame const *m_GamePlugin;
mutable QSettings m_Settings;
+ GeometrySettings m_Geometry;
LoadMechanism m_LoadMechanism;
std::vector<MOBase::IPlugin*> m_Plugins;