980bac5c4e
The dialog would default to CWD because the contents of the line edit where not an absolute path.
200 lines
7.8 KiB
Python
200 lines
7.8 KiB
Python
import os.path
|
|
import platform as pf
|
|
from logging import getLogger
|
|
from typing import Tuple
|
|
|
|
from PyQt5.QtCore import Qt, pyqtSlot
|
|
from PyQt5.QtGui import QShowEvent
|
|
from PyQt5.QtWidgets import QFileDialog, QComboBox, QLineEdit
|
|
from legendary.models.game import Game, InstalledGame
|
|
|
|
from rare.components.tabs.settings.widgets.env_vars import EnvVars
|
|
from rare.components.tabs.settings.widgets.game import GameSettingsBase
|
|
from rare.components.tabs.settings.widgets.launch import LaunchSettingsBase
|
|
from rare.components.tabs.settings.widgets.overlay import DxvkSettings
|
|
from rare.components.tabs.settings.widgets.wrappers import WrapperSettings
|
|
from rare.models.game import RareGame
|
|
from rare.utils import config_helper as config
|
|
from rare.widgets.indicator_edit import PathEdit, IndicatorReasonsCommon
|
|
|
|
if pf.system() != "Windows":
|
|
from rare.components.tabs.settings.widgets.wine import WineSettings
|
|
|
|
if pf.system() in {"Linux", "FreeBSD"}:
|
|
from rare.components.tabs.settings.widgets.proton import ProtonSettings
|
|
from rare.components.tabs.settings.widgets.overlay import MangoHudSettings
|
|
|
|
logger = getLogger("GameSettings")
|
|
|
|
|
|
class GameWrapperSettings(WrapperSettings):
|
|
def __init__(self, parent=None):
|
|
super().__init__(parent=parent)
|
|
|
|
def load_settings(self, app_name: str):
|
|
self.app_name = app_name
|
|
|
|
|
|
class GameLaunchSettings(LaunchSettingsBase):
|
|
|
|
def __init__(self, parent=None):
|
|
super(GameLaunchSettings, self).__init__(GameWrapperSettings, parent=parent)
|
|
|
|
self.game: Game = None
|
|
self.igame: InstalledGame = None
|
|
|
|
self.skip_update_combo = QComboBox(self)
|
|
self.skip_update_combo.addItem(self.tr("Default"), None)
|
|
self.skip_update_combo.addItem(self.tr("No"), "false")
|
|
self.skip_update_combo.addItem(self.tr("Yes"), "true")
|
|
self.skip_update_combo.currentIndexChanged.connect(self.__skip_update_changed)
|
|
|
|
self.offline_combo = QComboBox(self)
|
|
self.offline_combo.addItem(self.tr("Default"), None)
|
|
self.offline_combo.addItem(self.tr("No"), "false")
|
|
self.offline_combo.addItem(self.tr("Yes"), "true")
|
|
self.offline_combo.currentIndexChanged.connect(self.__offline_changed)
|
|
|
|
self.override_exe_edit = PathEdit(
|
|
file_mode=QFileDialog.ExistingFile,
|
|
name_filters=["*.exe", "*.app"],
|
|
placeholder=self.tr("Relative path to the replacement executable"),
|
|
edit_func=self.__override_exe_edit_callback,
|
|
save_func=self.__override_exe_save_callback,
|
|
parent=self
|
|
)
|
|
|
|
self.launch_params_edit = QLineEdit(self)
|
|
self.launch_params_edit.setPlaceholderText(self.tr("Game specific command line arguments"))
|
|
self.launch_params_edit.textChanged.connect(self.__launch_params_changed)
|
|
|
|
self.main_layout.insertRow(0, self.tr("Skip update check"), self.skip_update_combo)
|
|
self.main_layout.insertRow(1, self.tr("Offline mode"), self.offline_combo)
|
|
self.main_layout.insertRow(2, self.tr("Launch parameters"), self.launch_params_edit)
|
|
self.main_layout.insertRow(3, self.tr("Override executable"), self.override_exe_edit)
|
|
|
|
def showEvent(self, a0: QShowEvent):
|
|
if a0.spontaneous():
|
|
return super().showEvent(a0)
|
|
|
|
skip_update = config.get_option(self.app_name, "skip_update_check", fallback=None)
|
|
self.skip_update_combo.setCurrentIndex(self.offline_combo.findData(skip_update, Qt.UserRole))
|
|
|
|
offline = config.get_option(self.app_name, "offline", fallback=None)
|
|
self.offline_combo.setCurrentIndex(self.offline_combo.findData(offline, Qt.UserRole))
|
|
|
|
if self.igame:
|
|
self.offline_combo.setEnabled(self.igame.can_run_offline)
|
|
self.override_exe_edit.setRootPath(self.igame.install_path)
|
|
else:
|
|
self.offline_combo.setEnabled(False)
|
|
self.override_exe_edit.setRootPath(os.path.expanduser("~/"))
|
|
|
|
launch_params = config.get_option(self.app_name, "start_params", "")
|
|
self.launch_params_edit.setText(launch_params)
|
|
|
|
override_exe = config.get_option(self.app_name, "override_exe", fallback="")
|
|
self.override_exe_edit.setText(override_exe)
|
|
|
|
return super().showEvent(a0)
|
|
|
|
@pyqtSlot(int)
|
|
def __skip_update_changed(self, index):
|
|
data = self.skip_update_combo.itemData(index, Qt.UserRole)
|
|
config.save_option(self.app_name, "skip_update_check", data)
|
|
|
|
def __override_exe_edit_callback(self, path: str) -> Tuple[bool, str, int]:
|
|
if not path or self.igame is None:
|
|
return True, path, IndicatorReasonsCommon.VALID
|
|
if not os.path.isabs(path):
|
|
path = os.path.join(self.igame.install_path, path)
|
|
# lk: Compare paths through python's commonpath because in windows we
|
|
# cannot compare as strings
|
|
# antonia disapproves of this
|
|
if os.path.commonpath([self.igame.install_path, path]) != self.igame.install_path:
|
|
return False, self.igame.install_path, IndicatorReasonsCommon.WRONG_PATH
|
|
if not os.path.exists(path):
|
|
return False, path, IndicatorReasonsCommon.WRONG_PATH
|
|
|
|
if not path.endswith(".exe") and not path.endswith(".app"):
|
|
return False, path, IndicatorReasonsCommon.WRONG_PATH
|
|
path = os.path.relpath(path, self.igame.install_path)
|
|
return True, path, IndicatorReasonsCommon.VALID
|
|
|
|
def __override_exe_save_callback(self, path: str):
|
|
config.save_option(self.app_name, "override_exe", path)
|
|
|
|
@pyqtSlot(int)
|
|
def __offline_changed(self, index):
|
|
data = self.skip_update_combo.itemData(index, Qt.UserRole)
|
|
config.save_option(self.app_name, "offline", data)
|
|
|
|
def __launch_params_changed(self, value) -> None:
|
|
config.save_option(self.app_name, "start_params", value)
|
|
|
|
def load_settings(self, rgame: RareGame):
|
|
self.game = rgame.game
|
|
self.igame = rgame.igame
|
|
self.app_name = rgame.app_name
|
|
self.wrappers_widget.load_settings(rgame.app_name)
|
|
|
|
|
|
if pf.system() != "Windows":
|
|
|
|
class GameWineSettings(WineSettings):
|
|
def load_settings(self, app_name):
|
|
self.app_name = app_name
|
|
|
|
|
|
if pf.system() in {"Linux", "FreeBSD"}:
|
|
|
|
class GameProtonSettings(ProtonSettings):
|
|
def load_settings(self, app_name: str):
|
|
self.app_name = app_name
|
|
|
|
class GameMangoHudSettings(MangoHudSettings):
|
|
def load_settings(self, app_name: str):
|
|
self.app_name = app_name
|
|
|
|
|
|
class GameDxvkSettings(DxvkSettings):
|
|
def load_settings(self, app_name: str):
|
|
self.app_name = app_name
|
|
|
|
|
|
class GameEnvVars(EnvVars):
|
|
def load_settings(self, app_name):
|
|
self.app_name = app_name
|
|
|
|
|
|
class GameSettings(GameSettingsBase):
|
|
def __init__(self, parent=None):
|
|
if pf.system() in {"Linux", "FreeBSD"}:
|
|
super(GameSettings, self).__init__(
|
|
GameLaunchSettings, GameDxvkSettings, GameEnvVars,
|
|
GameWineSettings, GameProtonSettings, GameMangoHudSettings,
|
|
parent=parent
|
|
)
|
|
elif pf.system() != "Windows":
|
|
super(GameSettings, self).__init__(
|
|
GameLaunchSettings, GameDxvkSettings, GameEnvVars,
|
|
GameWineSettings,
|
|
parent=parent
|
|
)
|
|
else:
|
|
super(GameSettings, self).__init__(
|
|
GameLaunchSettings, GameDxvkSettings, GameEnvVars,
|
|
parent=parent
|
|
)
|
|
|
|
def load_settings(self, rgame: RareGame):
|
|
self.set_title.emit(rgame.app_title)
|
|
self.app_name = rgame.app_name
|
|
self.launch.load_settings(rgame)
|
|
if pf.system() != "Windows":
|
|
self.wine.load_settings(rgame.app_name)
|
|
if pf.system() in {"Linux", "FreeBSD"}:
|
|
self.proton_tool.load_settings(rgame.app_name)
|
|
self.mangohud.load_settings(rgame.app_name)
|
|
self.dxvk.load_settings(rgame.app_name)
|
|
self.env_vars.load_settings(rgame.app_name)
|