1
Fork 0
mirror of https://github.com/redstrate/Astra.git synced 2025-04-23 04:57:44 +00:00
astra/src/settingswindow.cpp

521 lines
18 KiB
C++
Raw Normal View History

2021-11-01 13:14:00 -04:00
#include "settingswindow.h"
#include <QFormLayout>
#include <QPushButton>
#include <QDesktopServices>
2021-11-01 13:35:27 -04:00
#include <QLabel>
#include <QFileDialog>
#include <QCheckBox>
#include <QGroupBox>
#include <QMessageBox>
#include <QProcess>
2021-11-09 10:37:48 -05:00
#include <QGridLayout>
#include <QToolTip>
2021-11-01 13:14:00 -04:00
#include "launchercore.h"
#include "launcherwindow.h"
2022-02-23 21:18:53 -05:00
#include "gamescopesettingswindow.h"
2021-11-01 13:14:00 -04:00
SettingsWindow::SettingsWindow(int defaultTab, LauncherWindow& window, LauncherCore& core, QWidget* parent) : core(core), window(window), QDialog(parent) {
2021-11-01 13:14:00 -04:00
setWindowTitle("Settings");
setWindowModality(Qt::WindowModality::ApplicationModal);
2022-02-24 08:48:14 -05:00
auto mainLayout = new QVBoxLayout(this);
2021-11-09 10:37:48 -05:00
setLayout(mainLayout);
2022-02-24 08:48:14 -05:00
auto tabWidget = new QTabWidget();
mainLayout->addWidget(tabWidget);
// general tab
{
auto generalTabWidget = new QWidget();
tabWidget->addTab(generalTabWidget, "General");
2022-02-24 08:48:14 -05:00
auto layout = new QFormLayout();
generalTabWidget->setLayout(layout);
2022-02-24 08:48:14 -05:00
closeWhenLaunched = new QCheckBox("Close Astra when game is launched");
connect(closeWhenLaunched, &QCheckBox::stateChanged, [&](int state) {
core.appSettings.closeWhenLaunched = state;
core.saveSettings();
});
layout->addWidget(closeWhenLaunched);
}
// profile tab
{
auto profileTabWidget = new QWidget();
tabWidget->addTab(profileTabWidget, "Profiles");
auto profileLayout = new QGridLayout();
profileTabWidget->setLayout(profileLayout);
profileWidget = new QListWidget();
profileWidget->addItem("INVALID *DEBUG*");
profileWidget->setCurrentRow(0);
connect(profileWidget, &QListWidget::currentRowChanged, this,
&SettingsWindow::reloadControls);
profileLayout->addWidget(profileWidget, 0, 0, 3, 1);
2021-11-01 13:14:00 -04:00
auto addProfileButton = new QPushButton("Add Profile");
connect(addProfileButton, &QPushButton::pressed, [=] {
profileWidget->setCurrentRow(this->core.addProfile());
2021-11-09 13:44:37 -05:00
this->core.saveSettings();
});
profileLayout->addWidget(addProfileButton, 3, 0);
2021-11-09 13:44:37 -05:00
deleteProfileButton = new QPushButton("Delete Profile");
connect(deleteProfileButton, &QPushButton::pressed, [=] {
profileWidget->setCurrentRow(
this->core.deleteProfile(getCurrentProfile().name));
2021-11-09 13:44:37 -05:00
this->core.saveSettings();
});
profileLayout->addWidget(deleteProfileButton, 0, 2);
2021-11-09 11:44:27 -05:00
nameEdit = new QLineEdit();
connect(nameEdit, &QLineEdit::editingFinished, [=] {
getCurrentProfile().name = nameEdit->text();
2021-11-09 12:10:52 -05:00
reloadControls();
this->core.saveSettings();
});
profileLayout->addWidget(nameEdit, 0, 1);
2021-11-09 12:10:52 -05:00
auto gameBox = new QGroupBox("Game Options");
auto gameBoxLayout = new QFormLayout();
gameBox->setLayout(gameBoxLayout);
profileLayout->addWidget(gameBox, 1, 1);
directXCombo = new QComboBox();
directXCombo->addItem("DirectX 11");
directXCombo->addItem("DirectX 9");
gameBoxLayout->addRow("DirectX Version", directXCombo);
2021-11-02 08:49:06 -04:00
connect(directXCombo,
static_cast<void (QComboBox::*)(int)>(
&QComboBox::currentIndexChanged),
[=](int index) {
getCurrentProfile().useDX9 =
directXCombo->currentIndex() == 1;
this->core.saveSettings();
});
2021-11-02 08:49:06 -04:00
currentGameDirectory = new QLineEdit();
currentGameDirectory->setReadOnly(true);
gameBoxLayout->addRow("Game Directory", currentGameDirectory);
auto gameDirButtonLayout = new QHBoxLayout();
auto gameDirButtonContainer = new QWidget();
gameDirButtonContainer->setLayout(gameDirButtonLayout);
gameBoxLayout->addWidget(gameDirButtonContainer);
auto selectDirectoryButton = new QPushButton("Select Game Directory");
connect(selectDirectoryButton, &QPushButton::pressed, [this] {
getCurrentProfile().gamePath =
QFileDialog::getExistingDirectory(this, "Open Game Directory");
this->reloadControls();
this->core.saveSettings();
this->core.readGameVersion();
});
gameDirButtonLayout->addWidget(selectDirectoryButton);
auto gameDirectoryButton = new QPushButton("Open Game Directory");
connect(gameDirectoryButton, &QPushButton::pressed,
[&window, this] { window.openPath(getCurrentProfile().gamePath); });
gameDirButtonLayout->addWidget(gameDirectoryButton);
2022-01-27 09:25:23 -05:00
#ifdef ENABLE_WATCHDOG
enableWatchdog = new QCheckBox("Enable Watchdog (X11 only)");
gameBoxLayout->addWidget(enableWatchdog);
connect(enableWatchdog, &QCheckBox::stateChanged, [this](int state) {
getCurrentProfile().enableWatchdog = state;
this->core.saveSettings();
});
#endif
expansionVersionLabel = new QLabel();
gameBoxLayout->addRow("Game Version", expansionVersionLabel);
auto loginBox = new QGroupBox("Login Options");
auto loginBoxLayout = new QFormLayout();
loginBox->setLayout(loginBoxLayout);
2021-11-09 11:06:42 -05:00
profileLayout->addWidget(loginBox, 2, 1);
2021-11-09 11:06:42 -05:00
encryptArgumentsBox = new QCheckBox();
connect(encryptArgumentsBox, &QCheckBox::stateChanged, [=](int) {
getCurrentProfile().encryptArguments =
encryptArgumentsBox->isChecked();
2021-11-09 21:13:21 -05:00
this->core.saveSettings();
});
loginBoxLayout->addRow("Encrypt Game Arguments", encryptArgumentsBox);
2021-11-09 21:13:21 -05:00
serverType = new QComboBox();
serverType->insertItem(0, "Square Enix");
serverType->insertItem(1, "Sapphire");
2021-11-09 12:38:18 -05:00
connect(serverType,
static_cast<void (QComboBox::*)(int)>(
&QComboBox::currentIndexChanged),
[=](int index) {
getCurrentProfile().isSapphire = index == 1;
reloadControls();
this->core.saveSettings();
});
loginBoxLayout->addRow("Server Lobby", serverType);
gameLicenseBox = new QComboBox();
gameLicenseBox->insertItem(0, "Windows Standalone");
gameLicenseBox->insertItem(1, "Windows Steam");
gameLicenseBox->insertItem(2, "macOS");
connect(gameLicenseBox,
static_cast<void (QComboBox::*)(int)>(
&QComboBox::currentIndexChanged),
[=](int index) {
getCurrentProfile().license = (GameLicense)index;
this->core.saveSettings();
});
loginBoxLayout->addRow("Game License", gameLicenseBox);
lobbyServerURL = new QLineEdit();
connect(lobbyServerURL, &QLineEdit::editingFinished, [=] {
getCurrentProfile().lobbyURL = lobbyServerURL->text();
this->core.saveSettings();
});
loginBoxLayout->addRow("Lobby URL", lobbyServerURL);
rememberUsernameBox = new QCheckBox();
connect(rememberUsernameBox, &QCheckBox::stateChanged, [=](int) {
getCurrentProfile().rememberUsername =
rememberUsernameBox->isChecked();
this->core.saveSettings();
});
loginBoxLayout->addRow("Remember Username", rememberUsernameBox);
2021-11-09 11:06:42 -05:00
rememberPasswordBox = new QCheckBox();
connect(rememberPasswordBox, &QCheckBox::stateChanged, [=](int) {
getCurrentProfile().rememberPassword =
rememberPasswordBox->isChecked();
this->core.saveSettings();
});
loginBoxLayout->addRow("Remember Password", rememberPasswordBox);
2021-11-09 11:06:42 -05:00
2021-11-02 20:04:53 -04:00
#if defined(Q_OS_MAC) || defined(Q_OS_LINUX)
auto wineBox = new QGroupBox("Wine Options");
auto wineBoxLayout = new QFormLayout();
wineBox->setLayout(wineBoxLayout);
profileLayout->addWidget(wineBox, 1, 2, 1, 1);
2021-11-02 20:04:53 -04:00
winePathLabel = new QLineEdit();
winePathLabel->setReadOnly(true);
wineBoxLayout->addRow("Wine Executable", winePathLabel);
wineVersionCombo = new QComboBox();
#if defined(Q_OS_MAC)
wineVersionCombo->insertItem(2, "FFXIV Built-In");
#endif
wineVersionCombo->insertItem(0, "System Wine");
wineVersionCombo->insertItem(1, "Custom Path...");
wineBoxLayout->addWidget(wineVersionCombo);
selectWineButton = new QPushButton("Select Wine Executable");
wineBoxLayout->addWidget(selectWineButton);
connect(wineVersionCombo,
static_cast<void (QComboBox::*)(int)>(
&QComboBox::currentIndexChanged),
[this](int index) {
getCurrentProfile().wineVersion = index;
this->core.readWineInfo(getCurrentProfile());
this->core.saveSettings();
this->reloadControls();
});
connect(selectWineButton, &QPushButton::pressed, [this] {
getCurrentProfile().winePath =
QFileDialog::getOpenFileName(this, "Open Wine Executable");
this->core.saveSettings();
this->reloadControls();
});
winePrefixDirectory = new QLineEdit();
winePrefixDirectory->setReadOnly(true);
wineBoxLayout->addRow("Wine Prefix", winePrefixDirectory);
auto winePrefixButtonLayout = new QHBoxLayout();
auto winePrefixButtonContainer = new QWidget();
winePrefixButtonContainer->setLayout(winePrefixButtonLayout);
wineBoxLayout->addWidget(winePrefixButtonContainer);
auto selectPrefixButton = new QPushButton("Select Wine Prefix");
connect(selectPrefixButton, &QPushButton::pressed, [this] {
getCurrentProfile().winePrefixPath =
QFileDialog::getExistingDirectory(this, "Open Wine Prefix");
this->core.saveSettings();
this->reloadControls();
});
winePrefixButtonLayout->addWidget(selectPrefixButton);
auto openPrefixButton = new QPushButton("Open Wine Prefix");
connect(openPrefixButton, &QPushButton::pressed,
[&window, this] { window.openPath(getCurrentProfile().winePrefixPath); });
winePrefixButtonLayout->addWidget(openPrefixButton);
auto enableDXVKhud = new QCheckBox("Enable DXVK HUD");
wineBoxLayout->addRow("Wine Tweaks", enableDXVKhud);
connect(enableDXVKhud, &QCheckBox::stateChanged, [this](int state) {
getCurrentProfile().enableDXVKhud = state;
this->core.settings.setValue("enableDXVKhud",
static_cast<bool>(state));
});
2021-11-02 20:04:53 -04:00
#endif
#if defined(Q_OS_LINUX)
useEsync = new QCheckBox(
"Use Better Sync Primitives (Esync, Fsync, and Futex2)");
wineBoxLayout->addWidget(useEsync);
auto esyncLabel = new QPushButton("?");
connect(esyncLabel, &QPushButton::pressed, [esyncLabel] {
QToolTip::showText(
esyncLabel->mapToGlobal(QPoint()),
"This may improve game performance, but requires a Wine and kernel with the patches included.");
});
wineBoxLayout->addWidget(esyncLabel);
connect(useEsync, &QCheckBox::stateChanged, [this](int state) {
getCurrentProfile().useEsync = state;
this->core.saveSettings();
});
useGamescope = new QCheckBox("Use Gamescope");
wineBoxLayout->addWidget(useGamescope);
auto gamescopeButtonLayout = new QHBoxLayout();
auto gamescopeButtonContainer = new QWidget();
gamescopeButtonContainer->setLayout(gamescopeButtonLayout);
wineBoxLayout->addWidget(gamescopeButtonContainer);
auto gamescopeLabel = new QPushButton("?");
connect(gamescopeLabel, &QPushButton::pressed, [gamescopeLabel] {
QToolTip::showText(
gamescopeLabel->mapToGlobal(QPoint()),
"Use the micro-compositor compositor that uses Wayland and XWayland to create a nested session.\nIf you primarily use fullscreen mode, this may improve input handling especially on Wayland.");
});
gamescopeButtonLayout->addWidget(gamescopeLabel);
configureGamescopeButton = new QPushButton("Configure...");
connect(configureGamescopeButton, &QPushButton::pressed, [&] {
auto gamescopeSettingsWindow = new GamescopeSettingsWindow(
getCurrentProfile(), this->core, this);
gamescopeSettingsWindow->show();
});
gamescopeButtonLayout->addWidget(configureGamescopeButton);
connect(useGamescope, &QCheckBox::stateChanged, [this](int state) {
getCurrentProfile().useGamescope = state;
this->core.saveSettings();
this->reloadControls();
});
useGamemode = new QCheckBox("Use GameMode");
wineBoxLayout->addWidget(useGamemode);
auto gamemodeLabel = new QPushButton("?");
connect(gamemodeLabel, &QPushButton::pressed, [gamemodeLabel] {
QToolTip::showText(
gamemodeLabel->mapToGlobal(QPoint()),
"A special game performance enhancer, which automatically tunes your CPU scheduler among other things. This may improve game performance.");
});
wineBoxLayout->addWidget(gamemodeLabel);
connect(useGamemode, &QCheckBox::stateChanged, [this](int state) {
getCurrentProfile().useGamemode = state;
this->core.saveSettings();
});
#endif
2021-11-09 11:44:27 -05:00
auto dalamudBox = new QGroupBox("Dalamud Options");
auto dalamudBoxLayout = new QFormLayout();
dalamudBox->setLayout(dalamudBoxLayout);
profileLayout->addWidget(dalamudBox, 2, 2, 1, 1);
enableDalamudBox = new QCheckBox();
connect(enableDalamudBox, &QCheckBox::stateChanged, [=](int) {
getCurrentProfile().dalamud.enabled = enableDalamudBox->isChecked();
this->core.saveSettings();
});
dalamudBoxLayout->addRow("Enable Dalamud Injection", enableDalamudBox);
dalamudOptOutBox = new QCheckBox();
connect(dalamudOptOutBox, &QCheckBox::stateChanged, [=](int) {
getCurrentProfile().dalamud.optOutOfMbCollection = dalamudOptOutBox->isChecked();
this->core.saveSettings();
});
dalamudBoxLayout->addRow("Opt Out of Automatic Marketboard Collection", dalamudOptOutBox);
dalamudVersionLabel = new QLabel();
dalamudBoxLayout->addRow("Dalamud Version", dalamudVersionLabel);
dalamudAssetVersionLabel = new QLabel();
dalamudBoxLayout->addRow("Dalamud Asset Version", dalamudAssetVersionLabel);
}
tabWidget->setCurrentIndex(defaultTab);
2021-11-09 11:44:27 -05:00
reloadControls();
}
void SettingsWindow::reloadControls() {
if(currentlyReloadingControls)
return;
currentlyReloadingControls = true;
auto oldRow = profileWidget->currentRow();
2021-11-09 11:44:27 -05:00
profileWidget->clear();
for(const auto& profile : core.profileList()) {
2021-11-09 11:44:27 -05:00
profileWidget->addItem(profile);
}
profileWidget->setCurrentRow(oldRow);
closeWhenLaunched->setChecked(core.appSettings.closeWhenLaunched);
2021-11-09 13:44:37 -05:00
// deleting the main profile is unsupported behavior
deleteProfileButton->setEnabled(core.profileList().size() > 1);
2021-11-09 13:44:37 -05:00
ProfileSettings& profile = core.getProfile(profileWidget->currentRow());
2021-11-09 12:10:52 -05:00
nameEdit->setText(profile.name);
// game
directXCombo->setCurrentIndex(profile.useDX9 ? 1 : 0);
currentGameDirectory->setText(profile.gamePath);
2021-11-09 12:38:18 -05:00
if(profile.installedMaxExpansion == -1) {
expansionVersionLabel->setText("No game installed.");
} else {
QString expacString;
2021-12-02 15:04:28 -05:00
expacString += "Boot";
expacString += QString(" (%1)\n").arg(profile.bootVersion);
if(profile.installedMaxExpansion >= 0) {
expacString += "A Realm Reborn";
expacString += QString(" (%1)\n").arg(profile.gameVersion);
}
if(profile.installedMaxExpansion >= 1) {
expacString += "Heavensward";
expacString += QString(" (%1)\n").arg(profile.expansionVersions[0]);
}
if(profile.installedMaxExpansion >= 2) {
expacString += "Stormblood";
expacString += QString(" (%1)\n").arg(profile.expansionVersions[1]);
}
if(profile.installedMaxExpansion >= 3) {
expacString += "Shadowbringers";
expacString += QString(" (%1)\n").arg(profile.expansionVersions[2]);
}
if(profile.installedMaxExpansion >= 4) {
expacString += "Endwalker";
expacString += QString(" (%1)\n").arg(profile.expansionVersions[3]);
}
expansionVersionLabel->setText(expacString);
}
// wine
wineVersionCombo->setCurrentIndex(profile.wineVersion);
selectWineButton->setEnabled(profile.wineVersion == 1);
winePathLabel->setText(profile.winePath);
winePrefixDirectory->setText(profile.winePrefixPath);
#if defined(Q_OS_LINUX)
useEsync->setChecked(profile.useEsync);
useGamescope->setChecked(profile.useGamescope);
useGamemode->setChecked(profile.useGamemode);
useGamemode->setEnabled(core.gamemodeAvailable);
useGamescope->setEnabled(core.gamescopeAvailable);
configureGamescopeButton->setEnabled(profile.useGamescope);
2022-01-27 09:25:23 -05:00
#endif
#ifdef ENABLE_WATCHDOG
enableWatchdog->setChecked(profile.enableWatchdog);
#endif
// login
2021-11-09 21:13:21 -05:00
encryptArgumentsBox->setChecked(profile.encryptArguments);
2021-11-09 12:38:18 -05:00
serverType->setCurrentIndex(profile.isSapphire ? 1 : 0);
lobbyServerURL->setEnabled(profile.isSapphire);
if(profile.isSapphire) {
lobbyServerURL->setText(profile.lobbyURL);
} else {
lobbyServerURL->setText("neolobby0X.ffxiv.com");
}
rememberUsernameBox->setChecked(profile.rememberUsername);
rememberPasswordBox->setChecked(profile.rememberPassword);
gameLicenseBox->setCurrentIndex((int)profile.license);
// dalamud
enableDalamudBox->setChecked(profile.dalamud.enabled);
if(core.dalamudVersion.isEmpty()) {
dalamudVersionLabel->setText("Dalamud is not installed.");
} else {
dalamudVersionLabel->setText(core.dalamudVersion);
}
if(core.dalamudAssetVersion == -1) {
dalamudAssetVersionLabel->setText("Dalamud assets are not installed.");
} else {
dalamudAssetVersionLabel->setText(QString::number(core.dalamudAssetVersion));
}
dalamudOptOutBox->setChecked(profile.dalamud.optOutOfMbCollection);
window.reloadControls();
currentlyReloadingControls = false;
}
2021-11-09 12:10:52 -05:00
ProfileSettings& SettingsWindow::getCurrentProfile() {
return this->core.getProfile(profileWidget->currentRow());
}