commit
2803319373
|
@ -20,7 +20,7 @@ AppDir:
|
||||||
id: io.github.dummerle.rare
|
id: io.github.dummerle.rare
|
||||||
name: Rare
|
name: Rare
|
||||||
icon: Rare
|
icon: Rare
|
||||||
version: 1.10.7
|
version: 1.10.9
|
||||||
exec: usr/bin/python3
|
exec: usr/bin/python3
|
||||||
exec_args: $APPDIR/usr/src/rare/main.py $@
|
exec_args: $APPDIR/usr/src/rare/main.py $@
|
||||||
apt:
|
apt:
|
||||||
|
|
|
@ -12,7 +12,7 @@ force-exclude = '''
|
||||||
|
|
||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "rare"
|
name = "rare"
|
||||||
version = "1.10.7"
|
version = "1.10.9"
|
||||||
description = "A GUI for Legendary"
|
description = "A GUI for Legendary"
|
||||||
authors = ["Dummerle"]
|
authors = ["Dummerle"]
|
||||||
license = "GPL3"
|
license = "GPL3"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
__version__ = "1.10.7"
|
__version__ = "1.10.9"
|
||||||
__codename__ = "Garlic Crab"
|
__codename__ = "Garlic Crab"
|
||||||
|
|
||||||
# For PyCharm profiler
|
# For PyCharm profiler
|
||||||
|
|
|
@ -45,8 +45,6 @@ class Rare(RareApp):
|
||||||
self.signals = RareCore.instance().signals()
|
self.signals = RareCore.instance().signals()
|
||||||
self.core = RareCore.instance().core()
|
self.core = RareCore.instance().core()
|
||||||
|
|
||||||
config_helper.init_config_handler(self.core)
|
|
||||||
|
|
||||||
lang = self.settings.value("language", self.core.language_code, type=str)
|
lang = self.settings.value("language", self.core.language_code, type=str)
|
||||||
self.load_translator(lang)
|
self.load_translator(lang)
|
||||||
|
|
||||||
|
|
|
@ -73,13 +73,15 @@ class InstallDialog(QDialog):
|
||||||
self.ui.install_dialog_label.setText(f'<h3>{header} "{self.rgame.app_title}"</h3>')
|
self.ui.install_dialog_label.setText(f'<h3>{header} "{self.rgame.app_title}"</h3>')
|
||||||
self.setWindowTitle(f'{header} "{self.rgame.app_title}" - {QCoreApplication.instance().applicationName()}')
|
self.setWindowTitle(f'{header} "{self.rgame.app_title}" - {QCoreApplication.instance().applicationName()}')
|
||||||
|
|
||||||
if not self.options.base_path:
|
if options.base_path:
|
||||||
self.options.base_path = self.core.lgd.config.get(
|
base_path = options.base_path
|
||||||
"Legendary", "install_dir", fallback=os.path.expanduser("~/legendary")
|
elif rgame.is_installed:
|
||||||
)
|
base_path = rgame.install_path
|
||||||
|
else:
|
||||||
|
base_path = self.core.get_default_install_dir(rgame.default_platform)
|
||||||
|
|
||||||
self.install_dir_edit = PathEdit(
|
self.install_dir_edit = PathEdit(
|
||||||
path=self.options.base_path,
|
path=base_path,
|
||||||
file_mode=QFileDialog.DirectoryOnly,
|
file_mode=QFileDialog.DirectoryOnly,
|
||||||
edit_func=self.option_changed,
|
edit_func=self.option_changed,
|
||||||
save_func=self.save_install_edit,
|
save_func=self.save_install_edit,
|
||||||
|
@ -90,36 +92,24 @@ class InstallDialog(QDialog):
|
||||||
QFormLayout.FieldRole, self.install_dir_edit
|
QFormLayout.FieldRole, self.install_dir_edit
|
||||||
)
|
)
|
||||||
|
|
||||||
if self.options.update:
|
self.install_dir_edit.setDisabled(rgame.is_installed)
|
||||||
self.ui.install_dir_label.setEnabled(False)
|
self.ui.install_dir_label.setDisabled(rgame.is_installed)
|
||||||
self.install_dir_edit.setEnabled(False)
|
self.ui.shortcut_label.setDisabled(rgame.is_installed)
|
||||||
self.ui.shortcut_label.setEnabled(False)
|
self.ui.shortcut_check.setDisabled(rgame.is_installed)
|
||||||
self.ui.shortcut_check.setEnabled(False)
|
self.ui.shortcut_check.setChecked(not rgame.is_installed and QSettings().value("create_shortcut", True, bool))
|
||||||
else:
|
|
||||||
self.ui.shortcut_check.setChecked(QSettings().value("create_shortcut", True, bool))
|
|
||||||
|
|
||||||
self.error_box()
|
self.error_box()
|
||||||
|
|
||||||
platforms = self.rgame.platforms
|
self.ui.platform_combo.addItems(reversed(rgame.platforms))
|
||||||
self.ui.platform_combo.addItems(reversed(platforms))
|
combo_text = rgame.igame.platform if rgame.is_installed else rgame.default_platform
|
||||||
self.ui.platform_combo.currentIndexChanged.connect(lambda: self.option_changed(None))
|
self.ui.platform_combo.setCurrentIndex(self.ui.platform_combo.findText(combo_text))
|
||||||
self.ui.platform_combo.currentIndexChanged.connect(lambda: self.error_box())
|
self.ui.platform_combo.currentIndexChanged.connect(lambda i: self.option_changed(None))
|
||||||
self.ui.platform_combo.currentIndexChanged.connect(
|
self.ui.platform_combo.currentIndexChanged.connect(self.check_incompatible_platform)
|
||||||
lambda i: self.error_box(
|
self.ui.platform_combo.currentIndexChanged.connect(self.reset_install_dir)
|
||||||
self.tr("Warning"),
|
self.ui.platform_combo.currentIndexChanged.connect(self.reset_sdl_list)
|
||||||
self.tr("You will not be able to run the game if you select <b>{}</b> as platform").format(
|
|
||||||
self.ui.platform_combo.itemText(i)
|
self.ui.platform_label.setDisabled(rgame.is_installed)
|
||||||
),
|
self.ui.platform_combo.setDisabled(rgame.is_installed)
|
||||||
)
|
|
||||||
if (self.ui.platform_combo.currentText() == "Mac" and pf.system() != "Darwin")
|
|
||||||
else None
|
|
||||||
)
|
|
||||||
self.ui.platform_combo.setCurrentIndex(
|
|
||||||
self.ui.platform_combo.findText(
|
|
||||||
"Mac" if (pf.system() == "Darwin" and "Mac" in platforms) else "Windows"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
self.ui.platform_combo.currentTextChanged.connect(self.setup_sdl_list)
|
|
||||||
|
|
||||||
self.advanced.ui.max_workers_spin.setValue(self.core.lgd.config.getint("Legendary", "max_workers", fallback=0))
|
self.advanced.ui.max_workers_spin.setValue(self.core.lgd.config.getint("Legendary", "max_workers", fallback=0))
|
||||||
self.advanced.ui.max_workers_spin.valueChanged.connect(self.option_changed)
|
self.advanced.ui.max_workers_spin.valueChanged.connect(self.option_changed)
|
||||||
|
@ -139,7 +129,10 @@ class InstallDialog(QDialog):
|
||||||
|
|
||||||
self.selectable_checks: List[TagCheckBox] = []
|
self.selectable_checks: List[TagCheckBox] = []
|
||||||
self.config_tags: Optional[List[str]] = None
|
self.config_tags: Optional[List[str]] = None
|
||||||
self.setup_sdl_list(self.ui.platform_combo.currentText())
|
|
||||||
|
self.reset_install_dir(self.ui.platform_combo.currentIndex())
|
||||||
|
self.reset_sdl_list(self.ui.platform_combo.currentIndex())
|
||||||
|
self.check_incompatible_platform(self.ui.platform_combo.currentIndex())
|
||||||
|
|
||||||
self.ui.install_button.setEnabled(False)
|
self.ui.install_button.setEnabled(False)
|
||||||
|
|
||||||
|
@ -155,9 +148,10 @@ class InstallDialog(QDialog):
|
||||||
self.selectable.setEnabled(False)
|
self.selectable.setEnabled(False)
|
||||||
|
|
||||||
if pf.system() == "Darwin":
|
if pf.system() == "Darwin":
|
||||||
|
self.ui.shortcut_label.setDisabled(True)
|
||||||
self.ui.shortcut_check.setDisabled(True)
|
self.ui.shortcut_check.setDisabled(True)
|
||||||
self.ui.shortcut_check.setChecked(False)
|
self.ui.shortcut_check.setChecked(False)
|
||||||
self.ui.shortcut_check.setToolTip(self.tr("Creating a shortcut is not supported on MacOS"))
|
self.ui.shortcut_check.setToolTip(self.tr("Creating a shortcut is not supported on macOS"))
|
||||||
|
|
||||||
self.advanced.ui.install_prereqs_label.setEnabled(False)
|
self.advanced.ui.install_prereqs_label.setEnabled(False)
|
||||||
self.advanced.ui.install_prereqs_check.setEnabled(False)
|
self.advanced.ui.install_prereqs_check.setEnabled(False)
|
||||||
|
@ -190,8 +184,16 @@ class InstallDialog(QDialog):
|
||||||
self.__on_verify()
|
self.__on_verify()
|
||||||
self.show()
|
self.show()
|
||||||
|
|
||||||
@pyqtSlot(str)
|
@pyqtSlot(int)
|
||||||
def setup_sdl_list(self, platform="Windows"):
|
def reset_install_dir(self, index: int):
|
||||||
|
if not self.rgame.is_installed:
|
||||||
|
platform = self.ui.platform_combo.itemText(index)
|
||||||
|
default_dir = self.core.get_default_install_dir(platform)
|
||||||
|
self.install_dir_edit.setText(default_dir)
|
||||||
|
|
||||||
|
@pyqtSlot(int)
|
||||||
|
def reset_sdl_list(self, index: int):
|
||||||
|
platform = self.ui.platform_combo.itemText(index)
|
||||||
for cb in self.selectable_checks:
|
for cb in self.selectable_checks:
|
||||||
cb.disconnect()
|
cb.disconnect()
|
||||||
cb.deleteLater()
|
cb.deleteLater()
|
||||||
|
@ -223,8 +225,19 @@ class InstallDialog(QDialog):
|
||||||
else:
|
else:
|
||||||
self.selectable.setDisabled(True)
|
self.selectable.setDisabled(True)
|
||||||
|
|
||||||
|
@pyqtSlot(int)
|
||||||
|
def check_incompatible_platform(self, index: int):
|
||||||
|
platform = self.ui.platform_combo.itemText(index)
|
||||||
|
if platform == "Mac" and pf.system() != "Darwin":
|
||||||
|
self.error_box(
|
||||||
|
self.tr("Warning"),
|
||||||
|
self.tr("You will not be able to run the game if you select <b>{}</b> as platform").format(platform)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
self.error_box()
|
||||||
|
|
||||||
def get_options(self):
|
def get_options(self):
|
||||||
self.options.base_path = self.install_dir_edit.text() if not self.options.update else None
|
self.options.base_path = "" if self.rgame.is_installed else self.install_dir_edit.text()
|
||||||
self.options.max_workers = self.advanced.ui.max_workers_spin.value()
|
self.options.max_workers = self.advanced.ui.max_workers_spin.value()
|
||||||
self.options.shared_memory = self.advanced.ui.max_memory_spin.value()
|
self.options.shared_memory = self.advanced.ui.max_memory_spin.value()
|
||||||
self.options.order_opt = self.advanced.ui.dl_optimizations_check.isChecked()
|
self.options.order_opt = self.advanced.ui.dl_optimizations_check.isChecked()
|
||||||
|
|
|
@ -346,5 +346,5 @@ class DownloadsTab(QWidget):
|
||||||
@pyqtSlot(RareGame, bool, str)
|
@pyqtSlot(RareGame, bool, str)
|
||||||
def __on_uninstall_worker_result(self, rgame: RareGame, success: bool, message: str):
|
def __on_uninstall_worker_result(self, rgame: RareGame, success: bool, message: str):
|
||||||
if not success:
|
if not success:
|
||||||
QMessageBox.warning(None, self.tr("Uninstall - {}").format(rgame.title), message, QMessageBox.Close)
|
QMessageBox.warning(None, self.tr("Uninstall - {}").format(rgame.app_title), message, QMessageBox.Close)
|
||||||
rgame.state = RareGame.State.IDLE
|
rgame.state = RareGame.State.IDLE
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
from logging import getLogger
|
from logging import getLogger
|
||||||
|
|
||||||
from PyQt5.QtCore import QSettings, Qt, pyqtSlot
|
from PyQt5.QtCore import QSettings, Qt, pyqtSlot
|
||||||
|
from PyQt5.QtGui import QShowEvent
|
||||||
from PyQt5.QtWidgets import QStackedWidget, QVBoxLayout, QWidget, QScrollArea, QFrame
|
from PyQt5.QtWidgets import QStackedWidget, QVBoxLayout, QWidget, QScrollArea, QFrame
|
||||||
|
|
||||||
from rare.models.game import RareGame
|
from rare.models.game import RareGame
|
||||||
|
@ -33,8 +34,6 @@ class GamesTab(QStackedWidget):
|
||||||
self.image_manager = ImageManagerSingleton()
|
self.image_manager = ImageManagerSingleton()
|
||||||
self.settings = QSettings()
|
self.settings = QSettings()
|
||||||
|
|
||||||
self.active_filter: int = 0
|
|
||||||
|
|
||||||
self.games_page = QWidget(parent=self)
|
self.games_page = QWidget(parent=self)
|
||||||
games_page_layout = QVBoxLayout(self.games_page)
|
games_page_layout = QVBoxLayout(self.games_page)
|
||||||
self.addWidget(self.games_page)
|
self.addWidget(self.games_page)
|
||||||
|
@ -69,6 +68,7 @@ class GamesTab(QStackedWidget):
|
||||||
|
|
||||||
self.icon_view = QWidget(self.icon_view_scroll)
|
self.icon_view = QWidget(self.icon_view_scroll)
|
||||||
icon_view_layout = LibraryLayout(self.icon_view)
|
icon_view_layout = LibraryLayout(self.icon_view)
|
||||||
|
icon_view_layout.setSpacing(9)
|
||||||
icon_view_layout.setContentsMargins(0, 13, 0, 13)
|
icon_view_layout.setContentsMargins(0, 13, 0, 13)
|
||||||
icon_view_layout.setAlignment(Qt.AlignTop)
|
icon_view_layout.setAlignment(Qt.AlignTop)
|
||||||
|
|
||||||
|
@ -97,16 +97,20 @@ class GamesTab(QStackedWidget):
|
||||||
self.head_bar.refresh_list.clicked.connect(self.library_controller.update_list)
|
self.head_bar.refresh_list.clicked.connect(self.library_controller.update_list)
|
||||||
self.head_bar.view.toggled.connect(self.toggle_view)
|
self.head_bar.view.toggled.connect(self.toggle_view)
|
||||||
|
|
||||||
f = self.settings.value("filter", 0, int)
|
self.active_filter: str = self.head_bar.filter.currentData(Qt.UserRole)
|
||||||
if f >= len(self.head_bar.available_filters):
|
|
||||||
f = 0
|
|
||||||
self.active_filter = self.head_bar.available_filters[f]
|
|
||||||
|
|
||||||
# signals
|
# signals
|
||||||
self.signals.game.installed.connect(self.update_count_games_label)
|
self.signals.game.installed.connect(self.update_count_games_label)
|
||||||
self.signals.game.uninstalled.connect(self.update_count_games_label)
|
self.signals.game.uninstalled.connect(self.update_count_games_label)
|
||||||
|
|
||||||
|
self.init = True
|
||||||
|
|
||||||
|
def showEvent(self, a0: QShowEvent):
|
||||||
|
if a0.spontaneous() or not self.init:
|
||||||
|
return super().showEvent(a0)
|
||||||
self.setup_game_list()
|
self.setup_game_list()
|
||||||
|
self.init = False
|
||||||
|
return super().showEvent(a0)
|
||||||
|
|
||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
def scroll_to_top(self):
|
def scroll_to_top(self):
|
||||||
|
@ -149,7 +153,7 @@ class GamesTab(QStackedWidget):
|
||||||
for rgame in self.rcore.games:
|
for rgame in self.rcore.games:
|
||||||
icon_widget, list_widget = self.add_library_widget(rgame)
|
icon_widget, list_widget = self.add_library_widget(rgame)
|
||||||
if not icon_widget or not list_widget:
|
if not icon_widget or not list_widget:
|
||||||
logger.warning(f"Excluding {rgame.app_name} from the game list")
|
logger.warning("Excluding %s from the game list", rgame.app_title)
|
||||||
continue
|
continue
|
||||||
self.icon_view.layout().addWidget(icon_widget)
|
self.icon_view.layout().addWidget(icon_widget)
|
||||||
self.list_view.layout().addWidget(list_widget)
|
self.list_view.layout().addWidget(list_widget)
|
||||||
|
@ -160,8 +164,7 @@ class GamesTab(QStackedWidget):
|
||||||
try:
|
try:
|
||||||
icon_widget, list_widget = self.library_controller.add_game(rgame)
|
icon_widget, list_widget = self.library_controller.add_game(rgame)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise e
|
logger.error("Could not add widget for %s to library: %s", rgame.app_name, e)
|
||||||
logger.error(f"{rgame.app_name} is broken. Don't add it to game list: {e}")
|
|
||||||
return None, None
|
return None, None
|
||||||
icon_widget.show_info.connect(self.show_game_info)
|
icon_widget.show_info.connect(self.show_game_info)
|
||||||
list_widget.show_info.connect(self.show_game_info)
|
list_widget.show_info.connect(self.show_game_info)
|
||||||
|
|
|
@ -144,10 +144,10 @@ class CloudSaves(QWidget, SideTabContents):
|
||||||
self.cloud_save_path_edit.setText("")
|
self.cloud_save_path_edit.setText("")
|
||||||
QMessageBox.warning(
|
QMessageBox.warning(
|
||||||
self,
|
self,
|
||||||
self.tr("Error - {}").format(self.rgame.title),
|
self.tr("Error - {}").format(self.rgame.app_title),
|
||||||
self.tr(
|
self.tr(
|
||||||
"Error while calculating path for <b>{}</b>. Insufficient permissions to create <b>{}</b>"
|
"Error while calculating path for <b>{}</b>. Insufficient permissions to create <b>{}</b>"
|
||||||
).format(self.rgame.title, path),
|
).format(self.rgame.app_title, path),
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
if not path:
|
if not path:
|
||||||
|
@ -217,7 +217,7 @@ class CloudSaves(QWidget, SideTabContents):
|
||||||
|
|
||||||
self.rgame = rgame
|
self.rgame = rgame
|
||||||
|
|
||||||
self.set_title.emit(rgame.title)
|
self.set_title.emit(rgame.app_title)
|
||||||
rgame.signals.widget.update.connect(self.__update_widget)
|
rgame.signals.widget.update.connect(self.__update_widget)
|
||||||
|
|
||||||
self.__update_widget()
|
self.__update_widget()
|
||||||
|
|
|
@ -121,7 +121,7 @@ class GameInfo(QWidget, SideTabContents):
|
||||||
if not os.path.exists(repair_file):
|
if not os.path.exists(repair_file):
|
||||||
QMessageBox.warning(
|
QMessageBox.warning(
|
||||||
self,
|
self,
|
||||||
self.tr("Error - {}").format(self.rgame.title),
|
self.tr("Error - {}").format(self.rgame.app_title),
|
||||||
self.tr(
|
self.tr(
|
||||||
"Repair file does not exist or game does not need a repair. Please verify game first"
|
"Repair file does not exist or game does not need a repair. Please verify game first"
|
||||||
),
|
),
|
||||||
|
@ -135,11 +135,11 @@ class GameInfo(QWidget, SideTabContents):
|
||||||
if rgame.has_update:
|
if rgame.has_update:
|
||||||
ans = QMessageBox.question(
|
ans = QMessageBox.question(
|
||||||
self,
|
self,
|
||||||
self.tr("Repair and update? - {}").format(self.rgame.title),
|
self.tr("Repair and update? - {}").format(self.rgame.app_title),
|
||||||
self.tr(
|
self.tr(
|
||||||
"There is an update for <b>{}</b> from <b>{}</b> to <b>{}</b>. "
|
"There is an update for <b>{}</b> from <b>{}</b> to <b>{}</b>. "
|
||||||
"Do you want to update the game while repairing it?"
|
"Do you want to update the game while repairing it?"
|
||||||
).format(rgame.title, rgame.version, rgame.remote_version),
|
).format(rgame.app_title, rgame.version, rgame.remote_version),
|
||||||
) == QMessageBox.Yes
|
) == QMessageBox.Yes
|
||||||
rgame.repair(repair_and_update=ans)
|
rgame.repair(repair_and_update=ans)
|
||||||
|
|
||||||
|
@ -147,7 +147,7 @@ class GameInfo(QWidget, SideTabContents):
|
||||||
def __on_worker_error(self, rgame: RareGame, message: str):
|
def __on_worker_error(self, rgame: RareGame, message: str):
|
||||||
QMessageBox.warning(
|
QMessageBox.warning(
|
||||||
self,
|
self,
|
||||||
self.tr("Error - {}").format(rgame.title),
|
self.tr("Error - {}").format(rgame.app_title),
|
||||||
message
|
message
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -155,11 +155,11 @@ class GameInfo(QWidget, SideTabContents):
|
||||||
def __on_verify(self):
|
def __on_verify(self):
|
||||||
""" This method is to be called from the button only """
|
""" This method is to be called from the button only """
|
||||||
if not os.path.exists(self.rgame.igame.install_path):
|
if not os.path.exists(self.rgame.igame.install_path):
|
||||||
logger.error(f"Installation path {self.rgame.igame.install_path} for {self.rgame.title} does not exist")
|
logger.error(f"Installation path {self.rgame.igame.install_path} for {self.rgame.app_title} does not exist")
|
||||||
QMessageBox.warning(
|
QMessageBox.warning(
|
||||||
self,
|
self,
|
||||||
self.tr("Error - {}").format(self.rgame.title),
|
self.tr("Error - {}").format(self.rgame.app_title),
|
||||||
self.tr("Installation path for <b>{}</b> does not exist. Cannot continue.").format(self.rgame.title),
|
self.tr("Installation path for <b>{}</b> does not exist. Cannot continue.").format(self.rgame.app_title),
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
self.verify_game(self.rgame)
|
self.verify_game(self.rgame)
|
||||||
|
@ -184,18 +184,18 @@ class GameInfo(QWidget, SideTabContents):
|
||||||
if success:
|
if success:
|
||||||
QMessageBox.information(
|
QMessageBox.information(
|
||||||
self,
|
self,
|
||||||
self.tr("Summary - {}").format(rgame.title),
|
self.tr("Summary - {}").format(rgame.app_title),
|
||||||
self.tr("<b>{}</b> has been verified successfully. "
|
self.tr("<b>{}</b> has been verified successfully. "
|
||||||
"No missing or corrupt files found").format(rgame.title),
|
"No missing or corrupt files found").format(rgame.app_title),
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
ans = QMessageBox.question(
|
ans = QMessageBox.question(
|
||||||
self,
|
self,
|
||||||
self.tr("Summary - {}").format(rgame.title),
|
self.tr("Summary - {}").format(rgame.app_title),
|
||||||
self.tr(
|
self.tr(
|
||||||
"<b>{}</b> failed verification, <b>{}</b> file(s) corrupted, <b>{}</b> file(s) are missing. "
|
"<b>{}</b> failed verification, <b>{}</b> file(s) corrupted, <b>{}</b> file(s) are missing. "
|
||||||
"Do you want to repair them?"
|
"Do you want to repair them?"
|
||||||
).format(rgame.title, failed, missing),
|
).format(rgame.app_title, failed, missing),
|
||||||
QMessageBox.Yes | QMessageBox.No,
|
QMessageBox.Yes | QMessageBox.No,
|
||||||
QMessageBox.Yes,
|
QMessageBox.Yes,
|
||||||
)
|
)
|
||||||
|
@ -216,7 +216,7 @@ class GameInfo(QWidget, SideTabContents):
|
||||||
if os.path.basename(self.rgame.install_path) in os.path.basename(item):
|
if os.path.basename(self.rgame.install_path) in os.path.basename(item):
|
||||||
ans = QMessageBox.question(
|
ans = QMessageBox.question(
|
||||||
self,
|
self,
|
||||||
self.tr("Move game? - {}").format(self.rgame.title),
|
self.tr("Move game? - {}").format(self.rgame.app_title),
|
||||||
self.tr(
|
self.tr(
|
||||||
"Destination <b>{}</b> already exists. "
|
"Destination <b>{}</b> already exists. "
|
||||||
"Are you sure you want to overwrite it?"
|
"Are you sure you want to overwrite it?"
|
||||||
|
@ -255,8 +255,8 @@ class GameInfo(QWidget, SideTabContents):
|
||||||
def __on_move_result(self, rgame: RareGame, dst_path: str):
|
def __on_move_result(self, rgame: RareGame, dst_path: str):
|
||||||
QMessageBox.information(
|
QMessageBox.information(
|
||||||
self,
|
self,
|
||||||
self.tr("Summary - {}").format(rgame.title),
|
self.tr("Summary - {}").format(rgame.app_title),
|
||||||
self.tr("<b>{}</b> successfully moved to <b>{}<b>.").format(rgame.title, dst_path),
|
self.tr("<b>{}</b> successfully moved to <b>{}<b>.").format(rgame.app_title, dst_path),
|
||||||
)
|
)
|
||||||
|
|
||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
|
@ -284,7 +284,9 @@ class GameInfo(QWidget, SideTabContents):
|
||||||
)
|
)
|
||||||
|
|
||||||
self.ui.platform.setText(
|
self.ui.platform.setText(
|
||||||
self.rgame.igame.platform if self.rgame.is_installed and not self.rgame.is_non_asset else "Windows"
|
self.rgame.igame.platform
|
||||||
|
if self.rgame.is_installed and not self.rgame.is_non_asset
|
||||||
|
else self.rgame.default_platform
|
||||||
)
|
)
|
||||||
|
|
||||||
self.ui.lbl_grade.setDisabled(
|
self.ui.lbl_grade.setDisabled(
|
||||||
|
|
|
@ -38,15 +38,15 @@ class LibraryWidgetController(QObject):
|
||||||
elif "hidden" in widget.rgame.metadata.tags:
|
elif "hidden" in widget.rgame.metadata.tags:
|
||||||
visible = False
|
visible = False
|
||||||
elif filter_name == "installed":
|
elif filter_name == "installed":
|
||||||
visible = widget.rgame.is_installed
|
visible = widget.rgame.is_installed and not widget.rgame.is_unreal
|
||||||
elif filter_name == "offline":
|
elif filter_name == "offline":
|
||||||
visible = widget.rgame.can_run_offline
|
visible = widget.rgame.can_run_offline and not widget.rgame.is_unreal
|
||||||
elif filter_name == "32bit":
|
elif filter_name == "32bit":
|
||||||
visible = widget.rgame.is_win32
|
visible = widget.rgame.is_win32 and not widget.rgame.is_unreal
|
||||||
elif filter_name == "mac":
|
elif filter_name == "mac":
|
||||||
visible = widget.rgame.is_mac
|
visible = widget.rgame.is_mac and not widget.rgame.is_unreal
|
||||||
elif filter_name == "installable":
|
elif filter_name == "installable":
|
||||||
visible = not widget.rgame.is_non_asset
|
visible = not widget.rgame.is_non_asset and not widget.rgame.is_unreal
|
||||||
elif filter_name == "include_ue":
|
elif filter_name == "include_ue":
|
||||||
visible = True
|
visible = True
|
||||||
elif filter_name == "all":
|
elif filter_name == "all":
|
||||||
|
|
|
@ -15,7 +15,7 @@ class IconGameWidget(GameWidget):
|
||||||
def __init__(self, rgame: RareGame, parent=None):
|
def __init__(self, rgame: RareGame, parent=None):
|
||||||
super().__init__(rgame, parent)
|
super().__init__(rgame, parent)
|
||||||
self.setObjectName(f"{rgame.app_name}")
|
self.setObjectName(f"{rgame.app_name}")
|
||||||
self.setFixedSize(ImageSize.Display)
|
self.setFixedSize(ImageSize.Library)
|
||||||
self.ui = IconWidget()
|
self.ui = IconWidget()
|
||||||
self.ui.setupUi(self)
|
self.ui.setupUi(self)
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
from PyQt5.QtCore import QSettings, pyqtSignal, pyqtSlot
|
import platform as pf
|
||||||
|
|
||||||
|
from PyQt5.QtCore import QSettings, pyqtSignal, pyqtSlot, Qt
|
||||||
from PyQt5.QtWidgets import (
|
from PyQt5.QtWidgets import (
|
||||||
QLabel,
|
QLabel,
|
||||||
QPushButton,
|
QPushButton,
|
||||||
|
@ -22,45 +24,28 @@ class GameListHeadBar(QWidget):
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
super(GameListHeadBar, self).__init__(parent=parent)
|
super(GameListHeadBar, self).__init__(parent=parent)
|
||||||
self.rcore = RareCore.instance()
|
self.rcore = RareCore.instance()
|
||||||
self.settings = QSettings()
|
self.settings = QSettings(self)
|
||||||
|
|
||||||
self.filter = QComboBox()
|
self.filter = QComboBox(self)
|
||||||
self.filter.addItems(
|
self.filter.addItem(self.tr("All games"), "all")
|
||||||
[
|
self.filter.addItem(self.tr("Installed"), "installed")
|
||||||
self.tr("All games"),
|
self.filter.addItem(self.tr("Offline"), "offline")
|
||||||
self.tr("Installed only"),
|
# self.filter.addItem(self.tr("Hidden"), "hidden")
|
||||||
self.tr("Offline Games"),
|
|
||||||
# self.tr("Hidden")
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
self.available_filters = [
|
|
||||||
"all",
|
|
||||||
"installed",
|
|
||||||
"offline",
|
|
||||||
# "hidden"
|
|
||||||
]
|
|
||||||
if self.rcore.bit32_games:
|
if self.rcore.bit32_games:
|
||||||
self.filter.addItem(self.tr("32 Bit Games"))
|
self.filter.addItem(self.tr("32bit games"), "32bit")
|
||||||
self.available_filters.append("32bit")
|
|
||||||
|
|
||||||
if self.rcore.mac_games:
|
if self.rcore.mac_games:
|
||||||
self.filter.addItem(self.tr("Mac games"))
|
self.filter.addItem(self.tr("macOS games"), "mac")
|
||||||
self.available_filters.append("mac")
|
|
||||||
|
|
||||||
if self.rcore.origin_games:
|
if self.rcore.origin_games:
|
||||||
self.filter.addItem(self.tr("Exclude Origin"))
|
self.filter.addItem(self.tr("Exclude Origin"), "installable")
|
||||||
self.available_filters.append("installable")
|
self.filter.addItem(self.tr("Include Unreal"), "include_ue")
|
||||||
|
|
||||||
self.filter.addItem(self.tr("Include Unreal Engine"))
|
|
||||||
self.available_filters.append("include_ue")
|
|
||||||
|
|
||||||
|
filter_default = "mac" if pf.system() == "Darwin" else "all"
|
||||||
|
filter_index = i if (i := self.filter.findData(filter_default, Qt.UserRole)) >= 0 else 0
|
||||||
try:
|
try:
|
||||||
self.filter.setCurrentIndex(self.settings.value("filter", 0, int))
|
self.filter.setCurrentIndex(self.settings.value("library_filter", filter_index, int))
|
||||||
except TypeError:
|
except TypeError:
|
||||||
self.settings.setValue("filter", 0)
|
self.settings.setValue("library_filter", filter_index)
|
||||||
self.filter.setCurrentIndex(0)
|
self.filter.setCurrentIndex(filter_index)
|
||||||
|
|
||||||
self.filter.currentIndexChanged.connect(self.filter_changed)
|
self.filter.currentIndexChanged.connect(self.filter_changed)
|
||||||
|
|
||||||
integrations_menu = QMenu(self)
|
integrations_menu = QMenu(self)
|
||||||
|
@ -139,6 +124,6 @@ class GameListHeadBar(QWidget):
|
||||||
self.rcore.fetch()
|
self.rcore.fetch()
|
||||||
|
|
||||||
@pyqtSlot(int)
|
@pyqtSlot(int)
|
||||||
def filter_changed(self, i: int):
|
def filter_changed(self, index: int):
|
||||||
self.filterChanged.emit(self.available_filters[i])
|
self.filterChanged.emit(self.filter.itemData(index, Qt.UserRole))
|
||||||
self.settings.setValue("filter", i)
|
self.settings.setValue("library_filter", index)
|
||||||
|
|
|
@ -213,9 +213,7 @@ class EOSGroup(QGroupBox, Ui_EosWidget):
|
||||||
self.enabled_cb.setChecked(enabled)
|
self.enabled_cb.setChecked(enabled)
|
||||||
|
|
||||||
def install_overlay(self, update=False):
|
def install_overlay(self, update=False):
|
||||||
base_path = os.path.join(
|
base_path = os.path.join(self.core.get_default_install_dir(), ".overlay")
|
||||||
self.core.lgd.config.get("Legendary", "install_dir", fallback=os.path.expanduser("~/legendary")),".overlay"
|
|
||||||
)
|
|
||||||
if update:
|
if update:
|
||||||
if not self.overlay:
|
if not self.overlay:
|
||||||
self.overlay_stack.setCurrentIndex(1)
|
self.overlay_stack.setCurrentIndex(1)
|
||||||
|
|
|
@ -72,8 +72,10 @@ class ImportWorker(QRunnable):
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
core: LegendaryCore, path: str,
|
core: LegendaryCore,
|
||||||
|
path: str,
|
||||||
app_name: str = None,
|
app_name: str = None,
|
||||||
|
platform: Optional[str] = None,
|
||||||
import_folder: bool = False,
|
import_folder: bool = False,
|
||||||
import_dlcs: bool = False,
|
import_dlcs: bool = False,
|
||||||
import_force: bool = False
|
import_force: bool = False
|
||||||
|
@ -86,6 +88,7 @@ class ImportWorker(QRunnable):
|
||||||
self.path = Path(path)
|
self.path = Path(path)
|
||||||
self.app_name = app_name
|
self.app_name = app_name
|
||||||
self.import_folder = import_folder
|
self.import_folder = import_folder
|
||||||
|
self.platform = platform if platform is not None else self.core.default_platform
|
||||||
self.import_dlcs = import_dlcs
|
self.import_dlcs = import_dlcs
|
||||||
self.import_force = import_force
|
self.import_force = import_force
|
||||||
|
|
||||||
|
@ -110,9 +113,13 @@ class ImportWorker(QRunnable):
|
||||||
result = ImportedGame(ImportResult.ERROR)
|
result = ImportedGame(ImportResult.ERROR)
|
||||||
result.path = str(path)
|
result.path = str(path)
|
||||||
if app_name or (app_name := find_app_name(str(path), self.core)):
|
if app_name or (app_name := find_app_name(str(path), self.core)):
|
||||||
|
game = self.core.get_game(app_name)
|
||||||
result.app_name = app_name
|
result.app_name = app_name
|
||||||
result.app_title = app_title = self.core.get_game(app_name).app_title
|
result.app_title = game.app_title
|
||||||
success, message = self.__import_game(path, app_name, app_title)
|
platform = self.platform
|
||||||
|
if platform not in self.core.get_game(app_name, update_meta=False).asset_infos:
|
||||||
|
platform = "Windows"
|
||||||
|
success, message = self.__import_game(path, app_name, platform)
|
||||||
if not success:
|
if not success:
|
||||||
result.result = ImportResult.FAILED
|
result.result = ImportResult.FAILED
|
||||||
result.message = message
|
result.message = message
|
||||||
|
@ -120,12 +127,13 @@ class ImportWorker(QRunnable):
|
||||||
result.result = ImportResult.SUCCESS
|
result.result = ImportResult.SUCCESS
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def __import_game(self, path: Path, app_name: str, app_title: str):
|
def __import_game(self, path: Path, app_name: str, platform: str):
|
||||||
cli = LegendaryCLI(self.core)
|
cli = LegendaryCLI(self.core)
|
||||||
status = LgndrIndirectStatus()
|
status = LgndrIndirectStatus()
|
||||||
args = LgndrImportGameArgs(
|
args = LgndrImportGameArgs(
|
||||||
app_path=str(path),
|
app_path=str(path),
|
||||||
app_name=app_name,
|
app_name=app_name,
|
||||||
|
platform=platform,
|
||||||
disable_check=self.import_force,
|
disable_check=self.import_force,
|
||||||
skip_dlcs=not self.import_dlcs,
|
skip_dlcs=not self.import_dlcs,
|
||||||
with_dlcs=self.import_dlcs,
|
with_dlcs=self.import_dlcs,
|
||||||
|
@ -192,7 +200,7 @@ class ImportGroup(QGroupBox):
|
||||||
self.__install_dirs: Set[str] = set()
|
self.__install_dirs: Set[str] = set()
|
||||||
|
|
||||||
self.path_edit = PathEdit(
|
self.path_edit = PathEdit(
|
||||||
self.core.get_default_install_dir(),
|
self.core.get_default_install_dir(self.core.default_platform),
|
||||||
QFileDialog.DirectoryOnly,
|
QFileDialog.DirectoryOnly,
|
||||||
edit_func=self.path_edit_callback,
|
edit_func=self.path_edit_callback,
|
||||||
parent=self,
|
parent=self,
|
||||||
|
@ -206,6 +214,7 @@ class ImportGroup(QGroupBox):
|
||||||
self.app_name_edit = IndicatorLineEdit(
|
self.app_name_edit = IndicatorLineEdit(
|
||||||
placeholder=self.tr("Use in case the app name was not found automatically"),
|
placeholder=self.tr("Use in case the app name was not found automatically"),
|
||||||
edit_func=self.app_name_edit_callback,
|
edit_func=self.app_name_edit_callback,
|
||||||
|
save_func=self.app_name_save_callback,
|
||||||
parent=self,
|
parent=self,
|
||||||
)
|
)
|
||||||
self.app_name_edit.textChanged.connect(self.app_name_changed)
|
self.app_name_edit.textChanged.connect(self.app_name_changed)
|
||||||
|
@ -247,8 +256,10 @@ class ImportGroup(QGroupBox):
|
||||||
|
|
||||||
def set_game(self, app_name: str):
|
def set_game(self, app_name: str):
|
||||||
if app_name:
|
if app_name:
|
||||||
folder = self.rcore.get_game(app_name).folder_name
|
rgame = self.rcore.get_game(app_name)
|
||||||
self.path_edit.setText(os.path.join(self.core.get_default_install_dir(), folder))
|
self.path_edit.setText(
|
||||||
|
os.path.join(self.core.get_default_install_dir(rgame.default_platform), rgame.folder_name)
|
||||||
|
)
|
||||||
self.app_name_edit.setText(app_name)
|
self.app_name_edit.setText(app_name)
|
||||||
|
|
||||||
def path_edit_callback(self, path) -> Tuple[bool, str, int]:
|
def path_edit_callback(self, path) -> Tuple[bool, str, int]:
|
||||||
|
@ -279,6 +290,12 @@ class ImportGroup(QGroupBox):
|
||||||
else:
|
else:
|
||||||
return False, text, IndicatorReasonsCommon.NOT_INSTALLED
|
return False, text, IndicatorReasonsCommon.NOT_INSTALLED
|
||||||
|
|
||||||
|
def app_name_save_callback(self, text) -> None:
|
||||||
|
rgame = self.rcore.get_game(text)
|
||||||
|
self.ui.platform_combo.clear()
|
||||||
|
self.ui.platform_combo.addItems(rgame.platforms)
|
||||||
|
self.ui.platform_combo.setCurrentText(rgame.default_platform)
|
||||||
|
|
||||||
@pyqtSlot(str)
|
@pyqtSlot(str)
|
||||||
def app_name_changed(self, app_name: str):
|
def app_name_changed(self, app_name: str):
|
||||||
self.info_label.setText("")
|
self.info_label.setText("")
|
||||||
|
@ -294,6 +311,14 @@ class ImportGroup(QGroupBox):
|
||||||
@pyqtSlot(int)
|
@pyqtSlot(int)
|
||||||
def import_folder_changed(self, state: Qt.CheckState):
|
def import_folder_changed(self, state: Qt.CheckState):
|
||||||
self.app_name_edit.setEnabled(not state)
|
self.app_name_edit.setEnabled(not state)
|
||||||
|
self.ui.platform_combo.setEnabled(not state)
|
||||||
|
self.ui.platform_combo.setToolTip(
|
||||||
|
self.tr(
|
||||||
|
"When importing multiple games, the current OS will be used at the"
|
||||||
|
" platform for the games that support it, otherwise the Windows version"
|
||||||
|
" will be imported."
|
||||||
|
) if state else ""
|
||||||
|
)
|
||||||
self.ui.import_dlcs_check.setCheckState(Qt.Unchecked)
|
self.ui.import_dlcs_check.setCheckState(Qt.Unchecked)
|
||||||
self.ui.import_force_check.setCheckState(Qt.Unchecked)
|
self.ui.import_force_check.setCheckState(Qt.Unchecked)
|
||||||
self.ui.import_dlcs_check.setEnabled(
|
self.ui.import_dlcs_check.setEnabled(
|
||||||
|
@ -322,10 +347,11 @@ class ImportGroup(QGroupBox):
|
||||||
self.worker = ImportWorker(
|
self.worker = ImportWorker(
|
||||||
self.core,
|
self.core,
|
||||||
path,
|
path,
|
||||||
self.app_name_edit.text(),
|
app_name=self.app_name_edit.text(),
|
||||||
self.ui.import_folder_check.isChecked(),
|
platform=self.ui.platform_combo.currentText() if not self.ui.import_folder_check.isChecked() else None,
|
||||||
self.ui.import_dlcs_check.isChecked(),
|
import_folder=self.ui.import_folder_check.isChecked(),
|
||||||
self.ui.import_force_check.isChecked()
|
import_dlcs=self.ui.import_dlcs_check.isChecked(),
|
||||||
|
import_force=self.ui.import_force_check.isChecked()
|
||||||
)
|
)
|
||||||
self.worker.signals.progress.connect(self.__on_import_progress)
|
self.worker.signals.progress.connect(self.__on_import_progress)
|
||||||
self.worker.signals.result.connect(self.__on_import_result)
|
self.worker.signals.result.connect(self.__on_import_result)
|
||||||
|
|
|
@ -74,7 +74,6 @@ class UbiConnectWorker(Worker):
|
||||||
def __init__(self, core: LegendaryCore, ubi_account_id, partner_link_id):
|
def __init__(self, core: LegendaryCore, ubi_account_id, partner_link_id):
|
||||||
super(UbiConnectWorker, self).__init__()
|
super(UbiConnectWorker, self).__init__()
|
||||||
self.signals = UbiConnectWorker.Signals()
|
self.signals = UbiConnectWorker.Signals()
|
||||||
self.setAutoDelete(True)
|
|
||||||
self.core = core
|
self.core = core
|
||||||
self.ubi_account_id = ubi_account_id
|
self.ubi_account_id = ubi_account_id
|
||||||
self.partner_link_id = partner_link_id
|
self.partner_link_id = partner_link_id
|
||||||
|
|
|
@ -40,8 +40,10 @@ class DefaultGameSettings(QWidget):
|
||||||
|
|
||||||
if platform.system() != "Windows":
|
if platform.system() != "Windows":
|
||||||
self.linux_settings = LinuxAppSettings()
|
self.linux_settings = LinuxAppSettings()
|
||||||
self.proton_settings = ProtonSettings(self.linux_settings, self.wrapper_settings)
|
if platform.system() != "Darwin":
|
||||||
self.ui.proton_layout.addWidget(self.proton_settings)
|
self.proton_settings = ProtonSettings(self.linux_settings, self.wrapper_settings)
|
||||||
|
self.ui.proton_layout.addWidget(self.proton_settings)
|
||||||
|
self.proton_settings.environ_changed.connect(self.env_vars.reset_model)
|
||||||
|
|
||||||
# FIXME: Remove the spacerItem and margins from the linux settings
|
# FIXME: Remove the spacerItem and margins from the linux settings
|
||||||
# FIXME: This should be handled differently at soem point in the future
|
# FIXME: This should be handled differently at soem point in the future
|
||||||
|
@ -57,8 +59,6 @@ class DefaultGameSettings(QWidget):
|
||||||
lambda active: self.wrapper_settings.add_wrapper("mangohud")
|
lambda active: self.wrapper_settings.add_wrapper("mangohud")
|
||||||
if active else self.wrapper_settings.delete_wrapper("mangohud"))
|
if active else self.wrapper_settings.delete_wrapper("mangohud"))
|
||||||
self.linux_settings.environ_changed.connect(self.env_vars.reset_model)
|
self.linux_settings.environ_changed.connect(self.env_vars.reset_model)
|
||||||
self.proton_settings.environ_changed.connect(self.env_vars.reset_model)
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
self.ui.linux_settings_widget.setVisible(False)
|
self.ui.linux_settings_widget.setVisible(False)
|
||||||
|
|
||||||
|
@ -77,7 +77,10 @@ class DefaultGameSettings(QWidget):
|
||||||
proton = self.wrapper_settings.wrappers.get("proton", "")
|
proton = self.wrapper_settings.wrappers.get("proton", "")
|
||||||
if proton:
|
if proton:
|
||||||
proton = proton.text
|
proton = proton.text
|
||||||
self.proton_settings.load_settings(app_name, proton)
|
if platform.system() != "Darwin":
|
||||||
|
self.proton_settings.load_settings(app_name, proton)
|
||||||
|
else:
|
||||||
|
proton = ""
|
||||||
if proton:
|
if proton:
|
||||||
self.linux_settings.ui.wine_groupbox.setEnabled(False)
|
self.linux_settings.ui.wine_groupbox.setEnabled(False)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import platform
|
import platform as pf
|
||||||
import re
|
import re
|
||||||
from logging import getLogger
|
from logging import getLogger
|
||||||
from typing import Tuple
|
from typing import Tuple, List
|
||||||
|
|
||||||
from PyQt5.QtCore import QObject, pyqtSignal, QThreadPool, QSettings
|
from PyQt5.QtCore import QObject, pyqtSignal, QThreadPool, QSettings
|
||||||
from PyQt5.QtWidgets import QSizePolicy, QWidget, QFileDialog, QMessageBox
|
from PyQt5.QtWidgets import QSizePolicy, QWidget, QFileDialog, QMessageBox
|
||||||
|
@ -19,14 +19,21 @@ class RefreshGameMetaWorker(Worker):
|
||||||
class Signals(QObject):
|
class Signals(QObject):
|
||||||
finished = pyqtSignal()
|
finished = pyqtSignal()
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, platforms: List[str], include_unreal: bool):
|
||||||
super(RefreshGameMetaWorker, self).__init__()
|
super(RefreshGameMetaWorker, self).__init__()
|
||||||
self.signals = RefreshGameMetaWorker.Signals()
|
self.signals = RefreshGameMetaWorker.Signals()
|
||||||
self.setAutoDelete(True)
|
|
||||||
self.core = LegendaryCoreSingleton()
|
self.core = LegendaryCoreSingleton()
|
||||||
|
if platforms:
|
||||||
|
self.platforms = platforms
|
||||||
|
else:
|
||||||
|
self.platforms = ["Windows"]
|
||||||
|
self.skip_ue = not include_unreal
|
||||||
|
|
||||||
def run_real(self) -> None:
|
def run_real(self) -> None:
|
||||||
self.core.get_game_and_dlc_list(True, force_refresh=True)
|
for platform in self.platforms:
|
||||||
|
self.core.get_game_and_dlc_list(
|
||||||
|
True, platform=platform, force_refresh=True, skip_ue=self.skip_ue
|
||||||
|
)
|
||||||
self.signals.finished.emit()
|
self.signals.finished.emit()
|
||||||
|
|
||||||
|
|
||||||
|
@ -34,15 +41,26 @@ class LegendarySettings(QWidget, Ui_LegendarySettings):
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
super(LegendarySettings, self).__init__(parent=parent)
|
super(LegendarySettings, self).__init__(parent=parent)
|
||||||
self.setupUi(self)
|
self.setupUi(self)
|
||||||
self.settings = QSettings()
|
self.settings = QSettings(self)
|
||||||
|
|
||||||
self.core = LegendaryCoreSingleton()
|
self.core = LegendaryCoreSingleton()
|
||||||
|
|
||||||
# Default installation directory
|
# Platform specific installation directory for macOS games
|
||||||
|
if pf.system() == "Darwin":
|
||||||
|
self.mac_install_dir = PathEdit(
|
||||||
|
self.core.get_default_install_dir("Mac"),
|
||||||
|
placeholder=self.tr("Default installation folder for macOS games"),
|
||||||
|
file_mode=QFileDialog.DirectoryOnly,
|
||||||
|
save_func=self.__mac_path_save,
|
||||||
|
)
|
||||||
|
self.install_dir_layout.addWidget(self.mac_install_dir)
|
||||||
|
|
||||||
|
# Platform-independent installation directory
|
||||||
self.install_dir = PathEdit(
|
self.install_dir = PathEdit(
|
||||||
self.core.get_default_install_dir(),
|
self.core.get_default_install_dir(),
|
||||||
|
placeholder=self.tr("Default installation folder for Windows games"),
|
||||||
file_mode=QFileDialog.DirectoryOnly,
|
file_mode=QFileDialog.DirectoryOnly,
|
||||||
save_func=self.path_save,
|
save_func=self.__win_path_save,
|
||||||
)
|
)
|
||||||
self.install_dir_layout.addWidget(self.install_dir)
|
self.install_dir_layout.addWidget(self.install_dir)
|
||||||
|
|
||||||
|
@ -82,20 +100,36 @@ class LegendarySettings(QWidget, Ui_LegendarySettings):
|
||||||
)
|
)
|
||||||
self.locale_layout.addWidget(self.locale_edit)
|
self.locale_layout.addWidget(self.locale_edit)
|
||||||
|
|
||||||
self.win32_cb.setChecked(self.settings.value("win32_meta", False, bool))
|
self.fetch_win32_check.setChecked(self.settings.value("win32_meta", False, bool))
|
||||||
self.win32_cb.stateChanged.connect(lambda: self.settings.setValue("win32_meta", self.win32_cb.isChecked()))
|
self.fetch_win32_check.stateChanged.connect(
|
||||||
|
lambda: self.settings.setValue("win32_meta", self.fetch_win32_check.isChecked())
|
||||||
|
)
|
||||||
|
|
||||||
self.mac_cb.setChecked(self.settings.value("mac_meta", platform.system() == "Darwin", bool))
|
self.fetch_macos_check.setChecked(self.settings.value("macos_meta", pf.system() == "Darwin", bool))
|
||||||
self.mac_cb.stateChanged.connect(lambda: self.settings.setValue("mac_meta", self.mac_cb.isChecked()))
|
self.fetch_macos_check.stateChanged.connect(
|
||||||
|
lambda: self.settings.setValue("macos_meta", self.fetch_macos_check.isChecked())
|
||||||
|
)
|
||||||
|
self.fetch_macos_check.setDisabled(pf.system() == "Darwin")
|
||||||
|
|
||||||
self.refresh_game_meta_btn.clicked.connect(self.refresh_game_meta)
|
self.fetch_unreal_check.setChecked(self.settings.value("unreal_meta", False, bool))
|
||||||
|
self.fetch_unreal_check.stateChanged.connect(
|
||||||
|
lambda: self.settings.setValue("unreal_meta", self.fetch_unreal_check.isChecked())
|
||||||
|
)
|
||||||
|
|
||||||
def refresh_game_meta(self):
|
self.refresh_metadata_button.clicked.connect(self.refresh_metadata)
|
||||||
self.refresh_game_meta_btn.setDisabled(True)
|
# FIXME: Disable the button for now because it interferes with RareCore
|
||||||
self.refresh_game_meta_btn.setText(self.tr("Loading"))
|
self.refresh_metadata_button.setEnabled(False)
|
||||||
worker = RefreshGameMetaWorker()
|
self.refresh_metadata_button.setVisible(False)
|
||||||
worker.signals.finished.connect(lambda: self.refresh_game_meta_btn.setDisabled(False))
|
|
||||||
worker.signals.finished.connect(lambda: self.refresh_game_meta_btn.setText(self.tr("Refresh game meta")))
|
def refresh_metadata(self):
|
||||||
|
self.refresh_metadata_button.setDisabled(True)
|
||||||
|
platforms = []
|
||||||
|
if self.fetch_win32_check.isChecked():
|
||||||
|
platforms.append("Win32")
|
||||||
|
if self.fetch_macos_check.isChecked():
|
||||||
|
platforms.append("Mac")
|
||||||
|
worker = RefreshGameMetaWorker(platforms, self.fetch_unreal_check.isChecked())
|
||||||
|
worker.signals.finished.connect(lambda: self.refresh_metadata_button.setDisabled(False))
|
||||||
QThreadPool.globalInstance().start(worker)
|
QThreadPool.globalInstance().start(worker)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -120,12 +154,20 @@ class LegendarySettings(QWidget, Ui_LegendarySettings):
|
||||||
self.core.lgd.config.remove_option("Legendary", "locale")
|
self.core.lgd.config.remove_option("Legendary", "locale")
|
||||||
self.core.lgd.save_config()
|
self.core.lgd.save_config()
|
||||||
|
|
||||||
def path_save(self, text: str):
|
def __mac_path_save(self, text: str) -> None:
|
||||||
self.core.lgd.config["Legendary"]["install_dir"] = text
|
self.__path_save(text, "mac_install_dir")
|
||||||
if not text and "install_dir" in self.core.lgd.config["Legendary"].keys():
|
|
||||||
self.core.lgd.config["Legendary"].pop("install_dir")
|
def __win_path_save(self, text: str) -> None:
|
||||||
|
self.__path_save(text, "install_dir")
|
||||||
|
if pf.system() != "Darwin":
|
||||||
|
self.__mac_path_save(text)
|
||||||
|
|
||||||
|
def __path_save(self, text: str, option: str = "Windows"):
|
||||||
|
self.core.lgd.config["Legendary"][option] = text
|
||||||
|
if not text and option in self.core.lgd.config["Legendary"].keys():
|
||||||
|
self.core.lgd.config["Legendary"].pop(option)
|
||||||
else:
|
else:
|
||||||
logger.debug(f"Set config install_dir to {text}")
|
logger.debug(f"Set %s option in config to %s", option, text)
|
||||||
self.core.lgd.save_config()
|
self.core.lgd.save_config()
|
||||||
|
|
||||||
def max_worker_save(self, workers: str):
|
def max_worker_save(self, workers: str):
|
||||||
|
|
|
@ -82,8 +82,6 @@ class RareSettings(QWidget, Ui_RareSettings):
|
||||||
self.style_select.setCurrentIndex(0)
|
self.style_select.setCurrentIndex(0)
|
||||||
self.style_select.currentIndexChanged.connect(self.on_style_select_changed)
|
self.style_select.currentIndexChanged.connect(self.on_style_select_changed)
|
||||||
|
|
||||||
self.interface_info.setVisible(False)
|
|
||||||
|
|
||||||
self.rpc = RPCSettings(self)
|
self.rpc = RPCSettings(self)
|
||||||
self.right_layout.insertWidget(1, self.rpc, alignment=Qt.AlignTop)
|
self.right_layout.insertWidget(1, self.rpc, alignment=Qt.AlignTop)
|
||||||
|
|
||||||
|
@ -203,7 +201,6 @@ class RareSettings(QWidget, Ui_RareSettings):
|
||||||
self.settings.setValue("color_scheme", "")
|
self.settings.setValue("color_scheme", "")
|
||||||
self.style_select.setDisabled(False)
|
self.style_select.setDisabled(False)
|
||||||
set_color_pallete("")
|
set_color_pallete("")
|
||||||
self.interface_info.setVisible(True)
|
|
||||||
|
|
||||||
def on_style_select_changed(self, style):
|
def on_style_select_changed(self, style):
|
||||||
if style:
|
if style:
|
||||||
|
@ -215,7 +212,6 @@ class RareSettings(QWidget, Ui_RareSettings):
|
||||||
self.settings.setValue("style_sheet", "")
|
self.settings.setValue("style_sheet", "")
|
||||||
self.color_select.setDisabled(False)
|
self.color_select.setDisabled(False)
|
||||||
set_style_sheet("")
|
set_style_sheet("")
|
||||||
self.interface_info.setVisible(True)
|
|
||||||
|
|
||||||
def open_dir(self):
|
def open_dir(self):
|
||||||
if platform.system() == "Windows":
|
if platform.system() == "Windows":
|
||||||
|
@ -230,7 +226,6 @@ class RareSettings(QWidget, Ui_RareSettings):
|
||||||
|
|
||||||
def update_lang(self, i: int):
|
def update_lang(self, i: int):
|
||||||
self.settings.setValue("language", languages[i][0])
|
self.settings.setValue("language", languages[i][0])
|
||||||
self.interface_info.setVisible(True)
|
|
||||||
|
|
||||||
def init_checkboxes(self, checkboxes):
|
def init_checkboxes(self, checkboxes):
|
||||||
for cb in checkboxes:
|
for cb in checkboxes:
|
||||||
|
|
|
@ -43,9 +43,9 @@ class LegendaryCLI(LegendaryCLIReal):
|
||||||
def unlock_installed(func):
|
def unlock_installed(func):
|
||||||
@functools.wraps(func)
|
@functools.wraps(func)
|
||||||
def unlock(self, *args, **kwargs):
|
def unlock(self, *args, **kwargs):
|
||||||
self.logger.debug("Using unlock decorator")
|
self.logger.debug("%s: Using unlock decorator", func.__name__)
|
||||||
if not self.core.lgd.lock_installed():
|
if not self.core.lgd.lock_installed():
|
||||||
self.logger.info("Data is locked, trying to forcufully release it")
|
self.logger.info("Data is locked, trying to forcefully release it")
|
||||||
# self.core.lgd._installed_lock.release(force=True)
|
# self.core.lgd._installed_lock.release(force=True)
|
||||||
try:
|
try:
|
||||||
ret = func(self, *args, **kwargs)
|
ret = func(self, *args, **kwargs)
|
||||||
|
|
|
@ -3,6 +3,7 @@ import json
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
from multiprocessing import Queue
|
from multiprocessing import Queue
|
||||||
|
from sys import platform as sys_platform
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
|
|
||||||
# On Windows the monkeypatching of `run_real` below doesn't work like on Linux
|
# On Windows the monkeypatching of `run_real` below doesn't work like on Linux
|
||||||
|
@ -17,8 +18,8 @@ from legendary.models.game import Game, InstalledGame
|
||||||
from legendary.models.manifest import ManifestMeta
|
from legendary.models.manifest import ManifestMeta
|
||||||
|
|
||||||
from rare.lgndr.downloader.mp.manager import DLManager
|
from rare.lgndr.downloader.mp.manager import DLManager
|
||||||
from rare.lgndr.lfs.lgndry import LGDLFS
|
|
||||||
from rare.lgndr.glue.exception import LgndrException, LgndrLogHandler
|
from rare.lgndr.glue.exception import LgndrException, LgndrLogHandler
|
||||||
|
from rare.lgndr.lfs.lgndry import LGDLFS
|
||||||
|
|
||||||
legendary.core.DLManager = DLManager
|
legendary.core.DLManager = DLManager
|
||||||
legendary.core.LGDLFS = LGDLFS
|
legendary.core.LGDLFS = LGDLFS
|
||||||
|
@ -30,6 +31,7 @@ class LegendaryCore(LegendaryCoreReal):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(LegendaryCore, self).__init__(*args, **kwargs)
|
super(LegendaryCore, self).__init__(*args, **kwargs)
|
||||||
self.log.info("Using Rare's LegendaryCore monkey")
|
self.log.info("Using Rare's LegendaryCore monkey")
|
||||||
|
self.log.info("Using config in %s", self.lgd.path.replace(os.getlogin(), "<username>"))
|
||||||
self.handler = LgndrLogHandler(logging.CRITICAL)
|
self.handler = LgndrLogHandler(logging.CRITICAL)
|
||||||
self.log.addHandler(self.handler)
|
self.log.addHandler(self.handler)
|
||||||
|
|
||||||
|
@ -37,9 +39,9 @@ class LegendaryCore(LegendaryCoreReal):
|
||||||
def unlock_installed(func):
|
def unlock_installed(func):
|
||||||
@functools.wraps(func)
|
@functools.wraps(func)
|
||||||
def unlock(self, *args, **kwargs):
|
def unlock(self, *args, **kwargs):
|
||||||
self.log.debug("Using unlock decorator")
|
self.log.debug("%s: Using unlock decorator", func.__name__)
|
||||||
if not self.lgd.lock_installed():
|
if not self.lgd.lock_installed():
|
||||||
self.log.info("Data is locked, trying to forcufully release it")
|
self.log.info("Data is locked, trying to forcefully release it")
|
||||||
# self.lgd._installed_lock.release(force=True)
|
# self.lgd._installed_lock.release(force=True)
|
||||||
try:
|
try:
|
||||||
ret = func(self, *args, **kwargs)
|
ret = func(self, *args, **kwargs)
|
||||||
|
@ -50,6 +52,18 @@ class LegendaryCore(LegendaryCoreReal):
|
||||||
return ret
|
return ret
|
||||||
return unlock
|
return unlock
|
||||||
|
|
||||||
|
@property
|
||||||
|
def default_platform(self) -> str:
|
||||||
|
os_default = "Mac" if sys_platform == "darwin" else "Windows"
|
||||||
|
usr_platform = self.lgd.config.get("Legendary", "default_platform", fallback=os_default)
|
||||||
|
return usr_platform if usr_platform in ("Windows", "Win32", "Mac") else os_default
|
||||||
|
|
||||||
|
def update_check_enabled(self):
|
||||||
|
return False
|
||||||
|
|
||||||
|
def update_notice_enabled(self):
|
||||||
|
return False
|
||||||
|
|
||||||
# skip_sync defaults to false but since Rare is persistent, skip by default
|
# skip_sync defaults to false but since Rare is persistent, skip by default
|
||||||
# def get_installed_game(self, app_name, skip_sync=True) -> InstalledGame:
|
# def get_installed_game(self, app_name, skip_sync=True) -> InstalledGame:
|
||||||
# return super(LegendaryCore, self).get_installed_game(app_name, skip_sync)
|
# return super(LegendaryCore, self).get_installed_game(app_name, skip_sync)
|
||||||
|
|
|
@ -18,6 +18,8 @@ def main() -> int:
|
||||||
sys.stderr = open(os.devnull, 'w')
|
sys.stderr = open(os.devnull, 'w')
|
||||||
|
|
||||||
os.environ["QT_QPA_PLATFORMTHEME"] = ""
|
os.environ["QT_QPA_PLATFORMTHEME"] = ""
|
||||||
|
if "LEGENDARY_CONFIG_PATH" in os.environ:
|
||||||
|
os.environ["LEGENDARY_CONFIG_PATH"] = os.path.expanduser(os.environ["LEGENDARY_CONFIG_PATH"])
|
||||||
|
|
||||||
# fix cx_freeze
|
# fix cx_freeze
|
||||||
multiprocessing.freeze_support()
|
multiprocessing.freeze_support()
|
||||||
|
|
|
@ -97,15 +97,11 @@ class RareGameBase(QObject):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def app_name(self) -> str:
|
def app_name(self) -> str:
|
||||||
return self.igame.app_name if self.igame is not None else self.game.app_name
|
return self.game.app_name
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def app_title(self) -> str:
|
def app_title(self) -> str:
|
||||||
return self.igame.title if self.igame is not None else self.game.app_title
|
return self.game.app_title
|
||||||
|
|
||||||
@property
|
|
||||||
def title(self) -> str:
|
|
||||||
return self.app_title
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
|
@ -125,6 +121,10 @@ class RareGameBase(QObject):
|
||||||
"""
|
"""
|
||||||
return tuple(self.game.asset_infos.keys())
|
return tuple(self.game.asset_infos.keys())
|
||||||
|
|
||||||
|
@property
|
||||||
|
def default_platform(self) -> str:
|
||||||
|
return self.core.default_platform if self.core.default_platform in self.platforms else "Windows"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_mac(self) -> bool:
|
def is_mac(self) -> bool:
|
||||||
"""!
|
"""!
|
||||||
|
@ -173,7 +173,7 @@ class RareGameBase(QObject):
|
||||||
|
|
||||||
@return str The current version of the game
|
@return str The current version of the game
|
||||||
"""
|
"""
|
||||||
return self.igame.version if self.igame is not None else self.game.app_version()
|
return self.igame.version if self.igame is not None else self.game.app_version(self.default_platform)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def install_path(self) -> Optional[str]:
|
def install_path(self) -> Optional[str]:
|
||||||
|
@ -234,7 +234,7 @@ class RareGameSlim(RareGameBase):
|
||||||
status, (dt_local, dt_remote) = self.save_game_state
|
status, (dt_local, dt_remote) = self.save_game_state
|
||||||
|
|
||||||
def _upload():
|
def _upload():
|
||||||
logger.info(f"Uploading save for {self.title}")
|
logger.info(f"Uploading save for {self.app_title}")
|
||||||
self.state = RareGameSlim.State.SYNCING
|
self.state = RareGameSlim.State.SYNCING
|
||||||
self.core.upload_save(self.app_name, self.igame.save_path, dt_local)
|
self.core.upload_save(self.app_name, self.igame.save_path, dt_local)
|
||||||
self.state = RareGameSlim.State.IDLE
|
self.state = RareGameSlim.State.IDLE
|
||||||
|
@ -246,7 +246,7 @@ class RareGameSlim(RareGameBase):
|
||||||
logger.warning("Can't upload non existing save")
|
logger.warning("Can't upload non existing save")
|
||||||
return
|
return
|
||||||
if self.state == RareGameSlim.State.SYNCING:
|
if self.state == RareGameSlim.State.SYNCING:
|
||||||
logger.error(f"{self.title} is already syncing")
|
logger.error(f"{self.app_title} is already syncing")
|
||||||
return
|
return
|
||||||
|
|
||||||
if thread:
|
if thread:
|
||||||
|
@ -259,7 +259,7 @@ class RareGameSlim(RareGameBase):
|
||||||
status, (dt_local, dt_remote) = self.save_game_state
|
status, (dt_local, dt_remote) = self.save_game_state
|
||||||
|
|
||||||
def _download():
|
def _download():
|
||||||
logger.info(f"Downloading save for {self.title}")
|
logger.info(f"Downloading save for {self.app_title}")
|
||||||
self.state = RareGameSlim.State.SYNCING
|
self.state = RareGameSlim.State.SYNCING
|
||||||
self.core.download_saves(self.app_name, self.latest_save.file.manifest_name, self.save_path)
|
self.core.download_saves(self.app_name, self.latest_save.file.manifest_name, self.save_path)
|
||||||
self.state = RareGameSlim.State.IDLE
|
self.state = RareGameSlim.State.IDLE
|
||||||
|
@ -271,7 +271,7 @@ class RareGameSlim(RareGameBase):
|
||||||
logger.error("Can't download non existing save")
|
logger.error("Can't download non existing save")
|
||||||
return
|
return
|
||||||
if self.state == RareGameSlim.State.SYNCING:
|
if self.state == RareGameSlim.State.SYNCING:
|
||||||
logger.error(f"{self.title} is already syncing")
|
logger.error(f"{self.app_title} is already syncing")
|
||||||
return
|
return
|
||||||
|
|
||||||
if thread:
|
if thread:
|
||||||
|
|
|
@ -166,7 +166,8 @@ class RareGame(RareGameSlim):
|
||||||
|
|
||||||
def update_game(self):
|
def update_game(self):
|
||||||
self.game = self.core.get_game(
|
self.game = self.core.get_game(
|
||||||
self.app_name, update_meta=False, platform=self.igame.platform if self.igame else "Windows"
|
self.app_name, update_meta=False,
|
||||||
|
platform=self.igame.platform if self.igame else self.default_platform
|
||||||
)
|
)
|
||||||
|
|
||||||
def update_igame(self):
|
def update_igame(self):
|
||||||
|
@ -228,7 +229,7 @@ class RareGame(RareGameSlim):
|
||||||
if self.igame is not None:
|
if self.igame is not None:
|
||||||
return self.game.app_version(self.igame.platform)
|
return self.game.app_version(self.igame.platform)
|
||||||
else:
|
else:
|
||||||
return self.game.app_version()
|
return self.game.app_version(self.default_platform)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def has_update(self) -> bool:
|
def has_update(self) -> bool:
|
||||||
|
|
|
@ -70,15 +70,15 @@ class ImageSize:
|
||||||
DisplayWide = Preset(1, 1, Orientation.Wide, base=ImageWide)
|
DisplayWide = Preset(1, 1, Orientation.Wide, base=ImageWide)
|
||||||
"""! @brief Size and pixel ratio for wide 16/9 image display"""
|
"""! @brief Size and pixel ratio for wide 16/9 image display"""
|
||||||
|
|
||||||
Wide = DisplayWide
|
LibraryWide = Preset(1.21, 1, Orientation.Wide, base=ImageWide)
|
||||||
|
|
||||||
Normal = Display
|
Library = Preset(1.21, 1, base=Image)
|
||||||
"""! @brief Same as Display"""
|
"""! @brief Same as Display"""
|
||||||
|
|
||||||
Small = Preset(3, 1, base=Image)
|
Small = Preset(3, 1, base=Image)
|
||||||
"""! @brief Small image size for displaying"""
|
"""! @brief Small image size for displaying"""
|
||||||
|
|
||||||
SmallWide = Preset(1, 1, Orientation.Wide, base=ImageWide)
|
SmallWide = Preset(3, 1, Orientation.Wide, base=ImageWide)
|
||||||
"""! @brief Small image size for displaying"""
|
"""! @brief Small image size for displaying"""
|
||||||
|
|
||||||
Smaller = Preset(4, 1, base=Image)
|
Smaller = Preset(4, 1, base=Image)
|
||||||
|
|
|
@ -4,7 +4,7 @@ import time
|
||||||
from argparse import Namespace
|
from argparse import Namespace
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
from logging import getLogger
|
from logging import getLogger
|
||||||
from typing import Dict, Iterator, Callable, Optional, List, Union, Iterable, Tuple
|
from typing import Dict, Iterator, Callable, Optional, List, Union, Iterable, Tuple, Set
|
||||||
|
|
||||||
from PyQt5.QtCore import QObject, pyqtSignal, QSettings, pyqtSlot, QThreadPool, QRunnable, QTimer
|
from PyQt5.QtCore import QObject, pyqtSignal, QSettings, pyqtSlot, QThreadPool, QRunnable, QTimer
|
||||||
from legendary.lfs.eos import EOSOverlayApp
|
from legendary.lfs.eos import EOSOverlayApp
|
||||||
|
@ -25,6 +25,7 @@ from .workers import (
|
||||||
)
|
)
|
||||||
from .workers.uninstall import uninstall_game
|
from .workers.uninstall import uninstall_game
|
||||||
from .workers.worker import QueueWorkerInfo, QueueWorkerState
|
from .workers.worker import QueueWorkerInfo, QueueWorkerState
|
||||||
|
from rare.utils import config_helper
|
||||||
|
|
||||||
logger = getLogger("RareCore")
|
logger = getLogger("RareCore")
|
||||||
|
|
||||||
|
@ -54,9 +55,10 @@ class RareCore(QObject):
|
||||||
self.args(args)
|
self.args(args)
|
||||||
self.signals(init=True)
|
self.signals(init=True)
|
||||||
self.core(init=True)
|
self.core(init=True)
|
||||||
|
config_helper.init_config_handler(self.__core)
|
||||||
self.image_manager(init=True)
|
self.image_manager(init=True)
|
||||||
|
|
||||||
self.settings = QSettings()
|
self.settings = QSettings(self)
|
||||||
|
|
||||||
self.queue_workers: List[QueueWorker] = []
|
self.queue_workers: List[QueueWorker] = []
|
||||||
self.queue_threadpool = QThreadPool()
|
self.queue_threadpool = QThreadPool()
|
||||||
|
@ -129,17 +131,44 @@ class RareCore(QObject):
|
||||||
try:
|
try:
|
||||||
self.__core = LegendaryCore()
|
self.__core = LegendaryCore()
|
||||||
except configparser.MissingSectionHeaderError as e:
|
except configparser.MissingSectionHeaderError as e:
|
||||||
logger.warning(f"Config is corrupt: {e}")
|
logger.warning("Config is corrupt: %s", e)
|
||||||
if config_path := os.environ.get("XDG_CONFIG_HOME"):
|
if config_path := os.environ.get('LEGENDARY_CONFIG_PATH'):
|
||||||
path = os.path.join(config_path, "legendary")
|
path = config_path
|
||||||
|
elif config_path := os.environ.get('XDG_CONFIG_HOME'):
|
||||||
|
path = os.path.join(config_path, 'legendary')
|
||||||
else:
|
else:
|
||||||
path = os.path.expanduser("~/.config/legendary")
|
path = os.path.expanduser('~/.config/legendary')
|
||||||
|
logger.info("Creating config in path: %s", config_path)
|
||||||
with open(os.path.join(path, "config.ini"), "w") as config_file:
|
with open(os.path.join(path, "config.ini"), "w") as config_file:
|
||||||
config_file.write("[Legendary]")
|
config_file.write("[Legendary]")
|
||||||
self.__core = LegendaryCore()
|
self.__core = LegendaryCore()
|
||||||
|
|
||||||
|
# Initialize sections if they don't exist
|
||||||
for section in ["Legendary", "default", "default.env"]:
|
for section in ["Legendary", "default", "default.env"]:
|
||||||
if section not in self.__core.lgd.config.sections():
|
if section not in self.__core.lgd.config.sections():
|
||||||
self.__core.lgd.config.add_section(section)
|
self.__core.lgd.config.add_section(section)
|
||||||
|
|
||||||
|
# Set some platform defaults if unset
|
||||||
|
def check_config(option: str, accepted: Set = None) -> bool:
|
||||||
|
_exists = self.__core.lgd.config.has_option("Legendary", option)
|
||||||
|
_value = self.__core.lgd.config.get("Legendary", option, fallback="")
|
||||||
|
_accepted = _value in accepted if accepted is not None else True
|
||||||
|
return _exists and bool(_value) and _accepted
|
||||||
|
|
||||||
|
if not check_config("default_platform", {"Windows", "Win32", "Mac"}):
|
||||||
|
self.__core.lgd.config.set("Legendary", "default_platform", self.__core.default_platform)
|
||||||
|
if not check_config("install_dir"):
|
||||||
|
self.__core.lgd.config.set(
|
||||||
|
"Legendary", "install_dir", self.__core.get_default_install_dir()
|
||||||
|
)
|
||||||
|
if not check_config("mac_install_dir"):
|
||||||
|
self.__core.lgd.config.set(
|
||||||
|
"Legendary", "mac_install_dir", self.__core.get_default_install_dir(self.__core.default_platform)
|
||||||
|
)
|
||||||
|
# Always set these options
|
||||||
|
# Avoid falling back to Windows games on macOS
|
||||||
|
self.__core.lgd.config.set("Legendary", "install_platform_fallback", 'false')
|
||||||
|
|
||||||
# workaround if egl sync enabled, but no programdata_path
|
# workaround if egl sync enabled, but no programdata_path
|
||||||
# programdata_path might be unset if logging in through the browser
|
# programdata_path might be unset if logging in through the browser
|
||||||
if self.__core.egl_sync_enabled:
|
if self.__core.egl_sync_enabled:
|
||||||
|
@ -148,6 +177,7 @@ class RareCore(QObject):
|
||||||
else:
|
else:
|
||||||
if not os.path.exists(self.__core.egl.programdata_path):
|
if not os.path.exists(self.__core.egl.programdata_path):
|
||||||
self.__core.lgd.config.remove_option("Legendary", "egl_sync")
|
self.__core.lgd.config.remove_option("Legendary", "egl_sync")
|
||||||
|
|
||||||
self.__core.lgd.save_config()
|
self.__core.lgd.save_config()
|
||||||
return self.__core
|
return self.__core
|
||||||
|
|
||||||
|
@ -176,7 +206,9 @@ class RareCore(QObject):
|
||||||
del self.__args
|
del self.__args
|
||||||
self.__args = None
|
self.__args = None
|
||||||
|
|
||||||
del self.__eos_overlay
|
# del self.__eos_overlay
|
||||||
|
self.__eos_overlay = None
|
||||||
|
|
||||||
RareCore.__instance = None
|
RareCore.__instance = None
|
||||||
super(RareCore, self).deleteLater()
|
super(RareCore, self).deleteLater()
|
||||||
|
|
||||||
|
@ -357,7 +389,7 @@ class RareCore(QObject):
|
||||||
yield game.game
|
yield game.game
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def dlcs(self) -> Dict[str, Game]:
|
def dlcs(self) -> Dict[str, set[RareGame]]:
|
||||||
"""!
|
"""!
|
||||||
RareGames that ARE DLCs themselves
|
RareGames that ARE DLCs themselves
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
|
import platform
|
||||||
import time
|
import time
|
||||||
from argparse import Namespace
|
from argparse import Namespace
|
||||||
from enum import IntEnum
|
from enum import IntEnum
|
||||||
from logging import getLogger
|
from logging import getLogger
|
||||||
|
|
||||||
from PyQt5.QtCore import QObject, pyqtSignal
|
from PyQt5.QtCore import QObject, pyqtSignal, QSettings
|
||||||
from requests.exceptions import ConnectionError, HTTPError
|
from requests.exceptions import ConnectionError, HTTPError
|
||||||
|
|
||||||
from rare.lgndr.core import LegendaryCore
|
from rare.lgndr.core import LegendaryCore
|
||||||
|
@ -27,19 +28,54 @@ class FetchWorker(Worker):
|
||||||
self.signals = FetchWorker.Signals()
|
self.signals = FetchWorker.Signals()
|
||||||
self.core = core
|
self.core = core
|
||||||
self.args = args
|
self.args = args
|
||||||
|
self.settings = QSettings()
|
||||||
|
|
||||||
def run_real(self):
|
def run_real(self):
|
||||||
# Fetch regular EGL games with assets
|
# Fetch regular EGL games with assets
|
||||||
self.signals.progress.emit(0, self.signals.tr("Updating game metadata"))
|
|
||||||
start_time = time.time()
|
start_time = time.time()
|
||||||
|
|
||||||
|
want_unreal = self.settings.value("unreal_meta", False, bool) or self.args.debug
|
||||||
|
want_win32 = self.settings.value("win32_meta", False, bool)
|
||||||
|
want_macos = self.settings.value("macos_meta", False, bool)
|
||||||
|
need_macos = platform.system() == "Darwin"
|
||||||
|
need_windows = not any([want_win32, want_macos, need_macos, self.args.debug])
|
||||||
|
|
||||||
|
if want_win32 or self.args.debug:
|
||||||
|
logger.info(
|
||||||
|
"Requesting Win32 metadata due to %s, %s Unreal engine",
|
||||||
|
"settings" if want_win32 else "debug",
|
||||||
|
"with" if want_unreal else "without"
|
||||||
|
)
|
||||||
|
self.signals.progress.emit(00, self.signals.tr("Updating game metadata for Windows"))
|
||||||
|
self.core.get_game_and_dlc_list(
|
||||||
|
update_assets=not self.args.offline, platform="Win32", skip_ue=not want_unreal
|
||||||
|
)
|
||||||
|
|
||||||
|
if need_macos or want_macos or self.args.debug:
|
||||||
|
logger.info(
|
||||||
|
"Requesting macOS metadata due to %s, %s Unreal engine",
|
||||||
|
"platform" if need_macos else "settings" if want_macos else "debug",
|
||||||
|
"with" if want_unreal else "without"
|
||||||
|
)
|
||||||
|
self.signals.progress.emit(15, self.signals.tr("Updating game metadata for macOS"))
|
||||||
|
self.core.get_game_and_dlc_list(
|
||||||
|
update_assets=not self.args.offline, platform="Mac", skip_ue=not want_unreal
|
||||||
|
)
|
||||||
|
|
||||||
|
if need_windows:
|
||||||
|
self.signals.progress.emit(00, self.signals.tr("Updating game metadata for Windows"))
|
||||||
|
logger.info(
|
||||||
|
"Requesting Windows metadata, %s Unreal engine",
|
||||||
|
"with" if want_unreal else "without"
|
||||||
|
)
|
||||||
games, dlc_dict = self.core.get_game_and_dlc_list(
|
games, dlc_dict = self.core.get_game_and_dlc_list(
|
||||||
update_assets=not self.args.offline, platform="Windows", skip_ue=False
|
update_assets=need_windows, platform="Windows", skip_ue=not want_unreal
|
||||||
)
|
)
|
||||||
logger.debug(f"Games {len(games)}, games with DLCs {len(dlc_dict)}")
|
logger.debug(f"Games {len(games)}, games with DLCs {len(dlc_dict)}")
|
||||||
logger.debug(f"Request games: {time.time() - start_time} seconds")
|
logger.debug(f"Request games: {time.time() - start_time} seconds")
|
||||||
|
|
||||||
# Fetch non-asset games
|
# Fetch non-asset games
|
||||||
self.signals.progress.emit(10, self.signals.tr("Updating non-asset metadata"))
|
self.signals.progress.emit(30, self.signals.tr("Updating non-asset game metadata"))
|
||||||
start_time = time.time()
|
start_time = time.time()
|
||||||
try:
|
try:
|
||||||
na_games, na_dlc_dict = self.core.get_non_asset_library_items(force_refresh=False, skip_ue=False)
|
na_games, na_dlc_dict = self.core.get_non_asset_library_items(force_refresh=False, skip_ue=False)
|
||||||
|
|
|
@ -104,17 +104,17 @@ class OriginWineWorker(QRunnable):
|
||||||
if install_dir:
|
if install_dir:
|
||||||
logger.debug("Found Unix install directory %s", install_dir)
|
logger.debug("Found Unix install directory %s", install_dir)
|
||||||
else:
|
else:
|
||||||
logger.info("Could not find Unix install directory for %s", rgame.title)
|
logger.info("Could not find Unix install directory for %s", rgame.app_title)
|
||||||
else:
|
else:
|
||||||
logger.info("Could not find Wine install directory for %s", rgame.title)
|
logger.info("Could not find Wine install directory for %s", rgame.app_title)
|
||||||
|
|
||||||
if install_dir:
|
if install_dir:
|
||||||
if os.path.isdir(install_dir):
|
if os.path.isdir(install_dir):
|
||||||
install_size = path_size(install_dir)
|
install_size = path_size(install_dir)
|
||||||
rgame.set_origin_attributes(install_dir, install_size)
|
rgame.set_origin_attributes(install_dir, install_size)
|
||||||
logger.info("Origin game %s (%s, %s)", rgame.title, install_dir, format_size(install_size))
|
logger.info("Origin game %s (%s, %s)", rgame.app_title, install_dir, format_size(install_size))
|
||||||
else:
|
else:
|
||||||
logger.warning("Origin game %s (%s does not exist)", rgame.title, install_dir)
|
logger.warning("Origin game %s (%s does not exist)", rgame.app_title, install_dir)
|
||||||
else:
|
else:
|
||||||
logger.info("Origin game %s is not installed", rgame.title)
|
logger.info("Origin game %s is not installed", rgame.app_title)
|
||||||
logger.info("Origin worker finished in %ss", time.time() - t)
|
logger.info("Origin worker finished in %ss", time.time() - t)
|
||||||
|
|
|
@ -14,7 +14,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets
|
||||||
class Ui_ImportGroup(object):
|
class Ui_ImportGroup(object):
|
||||||
def setupUi(self, ImportGroup):
|
def setupUi(self, ImportGroup):
|
||||||
ImportGroup.setObjectName("ImportGroup")
|
ImportGroup.setObjectName("ImportGroup")
|
||||||
ImportGroup.resize(506, 184)
|
ImportGroup.resize(651, 218)
|
||||||
ImportGroup.setWindowTitle("ImportGroup")
|
ImportGroup.setWindowTitle("ImportGroup")
|
||||||
ImportGroup.setWindowFilePath("")
|
ImportGroup.setWindowFilePath("")
|
||||||
self.import_layout = QtWidgets.QFormLayout(ImportGroup)
|
self.import_layout = QtWidgets.QFormLayout(ImportGroup)
|
||||||
|
@ -28,26 +28,35 @@ class Ui_ImportGroup(object):
|
||||||
self.import_layout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.app_name_label)
|
self.import_layout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.app_name_label)
|
||||||
self.import_folder_label = QtWidgets.QLabel(ImportGroup)
|
self.import_folder_label = QtWidgets.QLabel(ImportGroup)
|
||||||
self.import_folder_label.setObjectName("import_folder_label")
|
self.import_folder_label.setObjectName("import_folder_label")
|
||||||
self.import_layout.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.import_folder_label)
|
self.import_layout.setWidget(3, QtWidgets.QFormLayout.LabelRole, self.import_folder_label)
|
||||||
self.import_folder_check = QtWidgets.QCheckBox(ImportGroup)
|
self.import_folder_check = QtWidgets.QCheckBox(ImportGroup)
|
||||||
font = QtGui.QFont()
|
font = QtGui.QFont()
|
||||||
font.setItalic(True)
|
font.setItalic(True)
|
||||||
self.import_folder_check.setFont(font)
|
self.import_folder_check.setFont(font)
|
||||||
self.import_folder_check.setObjectName("import_folder_check")
|
self.import_folder_check.setObjectName("import_folder_check")
|
||||||
self.import_layout.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.import_folder_check)
|
self.import_layout.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.import_folder_check)
|
||||||
self.import_dlcs_label = QtWidgets.QLabel(ImportGroup)
|
self.import_dlcs_label = QtWidgets.QLabel(ImportGroup)
|
||||||
self.import_dlcs_label.setObjectName("import_dlcs_label")
|
self.import_dlcs_label.setObjectName("import_dlcs_label")
|
||||||
self.import_layout.setWidget(3, QtWidgets.QFormLayout.LabelRole, self.import_dlcs_label)
|
self.import_layout.setWidget(4, QtWidgets.QFormLayout.LabelRole, self.import_dlcs_label)
|
||||||
self.import_dlcs_check = QtWidgets.QCheckBox(ImportGroup)
|
self.import_dlcs_check = QtWidgets.QCheckBox(ImportGroup)
|
||||||
font = QtGui.QFont()
|
font = QtGui.QFont()
|
||||||
font.setItalic(True)
|
font.setItalic(True)
|
||||||
self.import_dlcs_check.setFont(font)
|
self.import_dlcs_check.setFont(font)
|
||||||
self.import_dlcs_check.setObjectName("import_dlcs_check")
|
self.import_dlcs_check.setObjectName("import_dlcs_check")
|
||||||
self.import_layout.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.import_dlcs_check)
|
self.import_layout.setWidget(4, QtWidgets.QFormLayout.FieldRole, self.import_dlcs_check)
|
||||||
|
self.import_force_label = QtWidgets.QLabel(ImportGroup)
|
||||||
|
self.import_force_label.setObjectName("import_force_label")
|
||||||
|
self.import_layout.setWidget(5, QtWidgets.QFormLayout.LabelRole, self.import_force_label)
|
||||||
|
self.import_force_check = QtWidgets.QCheckBox(ImportGroup)
|
||||||
|
font = QtGui.QFont()
|
||||||
|
font.setItalic(True)
|
||||||
|
self.import_force_check.setFont(font)
|
||||||
|
self.import_force_check.setObjectName("import_force_check")
|
||||||
|
self.import_layout.setWidget(5, QtWidgets.QFormLayout.FieldRole, self.import_force_check)
|
||||||
self.import_button_label = QtWidgets.QLabel(ImportGroup)
|
self.import_button_label = QtWidgets.QLabel(ImportGroup)
|
||||||
self.import_button_label.setText("Error")
|
self.import_button_label.setText("Error")
|
||||||
self.import_button_label.setObjectName("import_button_label")
|
self.import_button_label.setObjectName("import_button_label")
|
||||||
self.import_layout.setWidget(5, QtWidgets.QFormLayout.LabelRole, self.import_button_label)
|
self.import_layout.setWidget(6, QtWidgets.QFormLayout.LabelRole, self.import_button_label)
|
||||||
self.button_info_layout = QtWidgets.QHBoxLayout()
|
self.button_info_layout = QtWidgets.QHBoxLayout()
|
||||||
self.button_info_layout.setObjectName("button_info_layout")
|
self.button_info_layout.setObjectName("button_info_layout")
|
||||||
self.import_button = QtWidgets.QPushButton(ImportGroup)
|
self.import_button = QtWidgets.QPushButton(ImportGroup)
|
||||||
|
@ -58,16 +67,27 @@ class Ui_ImportGroup(object):
|
||||||
self.import_button.setSizePolicy(sizePolicy)
|
self.import_button.setSizePolicy(sizePolicy)
|
||||||
self.import_button.setObjectName("import_button")
|
self.import_button.setObjectName("import_button")
|
||||||
self.button_info_layout.addWidget(self.import_button)
|
self.button_info_layout.addWidget(self.import_button)
|
||||||
self.import_layout.setLayout(5, QtWidgets.QFormLayout.FieldRole, self.button_info_layout)
|
self.import_layout.setLayout(6, QtWidgets.QFormLayout.FieldRole, self.button_info_layout)
|
||||||
self.import_force_label = QtWidgets.QLabel(ImportGroup)
|
self.platform_label = QtWidgets.QLabel(ImportGroup)
|
||||||
self.import_force_label.setObjectName("import_force_label")
|
self.platform_label.setObjectName("platform_label")
|
||||||
self.import_layout.setWidget(4, QtWidgets.QFormLayout.LabelRole, self.import_force_label)
|
self.import_layout.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.platform_label)
|
||||||
self.import_force_check = QtWidgets.QCheckBox(ImportGroup)
|
self.platform_layout = QtWidgets.QHBoxLayout()
|
||||||
|
self.platform_layout.setObjectName("platform_layout")
|
||||||
|
self.platform_combo = QtWidgets.QComboBox(ImportGroup)
|
||||||
|
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
|
||||||
|
sizePolicy.setHorizontalStretch(0)
|
||||||
|
sizePolicy.setVerticalStretch(0)
|
||||||
|
sizePolicy.setHeightForWidth(self.platform_combo.sizePolicy().hasHeightForWidth())
|
||||||
|
self.platform_combo.setSizePolicy(sizePolicy)
|
||||||
|
self.platform_combo.setObjectName("platform_combo")
|
||||||
|
self.platform_layout.addWidget(self.platform_combo)
|
||||||
|
self.platform_tooltip = QtWidgets.QLabel(ImportGroup)
|
||||||
font = QtGui.QFont()
|
font = QtGui.QFont()
|
||||||
font.setItalic(True)
|
font.setItalic(True)
|
||||||
self.import_force_check.setFont(font)
|
self.platform_tooltip.setFont(font)
|
||||||
self.import_force_check.setObjectName("import_force_check")
|
self.platform_tooltip.setObjectName("platform_tooltip")
|
||||||
self.import_layout.setWidget(4, QtWidgets.QFormLayout.FieldRole, self.import_force_check)
|
self.platform_layout.addWidget(self.platform_tooltip)
|
||||||
|
self.import_layout.setLayout(2, QtWidgets.QFormLayout.FieldRole, self.platform_layout)
|
||||||
|
|
||||||
self.retranslateUi(ImportGroup)
|
self.retranslateUi(ImportGroup)
|
||||||
|
|
||||||
|
@ -80,9 +100,11 @@ class Ui_ImportGroup(object):
|
||||||
self.import_folder_check.setText(_translate("ImportGroup", "Scan the installation path for game folders and import them"))
|
self.import_folder_check.setText(_translate("ImportGroup", "Scan the installation path for game folders and import them"))
|
||||||
self.import_dlcs_label.setText(_translate("ImportGroup", "Import DLCs"))
|
self.import_dlcs_label.setText(_translate("ImportGroup", "Import DLCs"))
|
||||||
self.import_dlcs_check.setText(_translate("ImportGroup", "If a game has DLCs, try to import them too"))
|
self.import_dlcs_check.setText(_translate("ImportGroup", "If a game has DLCs, try to import them too"))
|
||||||
self.import_button.setText(_translate("ImportGroup", "Import Game"))
|
|
||||||
self.import_force_label.setText(_translate("ImportGroup", "Force import"))
|
self.import_force_label.setText(_translate("ImportGroup", "Force import"))
|
||||||
self.import_force_check.setText(_translate("ImportGroup", "Import game despite missing files"))
|
self.import_force_check.setText(_translate("ImportGroup", "Import game despite missing files"))
|
||||||
|
self.import_button.setText(_translate("ImportGroup", "Import Game"))
|
||||||
|
self.platform_label.setText(_translate("ImportGroup", "Platform"))
|
||||||
|
self.platform_tooltip.setText(_translate("ImportGroup", "Select the native platform of the game"))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>506</width>
|
<width>651</width>
|
||||||
<height>184</height>
|
<height>218</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
|
@ -37,14 +37,14 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0">
|
<item row="3" column="0">
|
||||||
<widget class="QLabel" name="import_folder_label">
|
<widget class="QLabel" name="import_folder_label">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Import all folders</string>
|
<string>Import all folders</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="1">
|
<item row="3" column="1">
|
||||||
<widget class="QCheckBox" name="import_folder_check">
|
<widget class="QCheckBox" name="import_folder_check">
|
||||||
<property name="font">
|
<property name="font">
|
||||||
<font>
|
<font>
|
||||||
|
@ -56,14 +56,14 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="0">
|
<item row="4" column="0">
|
||||||
<widget class="QLabel" name="import_dlcs_label">
|
<widget class="QLabel" name="import_dlcs_label">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Import DLCs</string>
|
<string>Import DLCs</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="1">
|
<item row="4" column="1">
|
||||||
<widget class="QCheckBox" name="import_dlcs_check">
|
<widget class="QCheckBox" name="import_dlcs_check">
|
||||||
<property name="font">
|
<property name="font">
|
||||||
<font>
|
<font>
|
||||||
|
@ -76,13 +76,32 @@
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="5" column="0">
|
<item row="5" column="0">
|
||||||
|
<widget class="QLabel" name="import_force_label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Force import</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="1">
|
||||||
|
<widget class="QCheckBox" name="import_force_check">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<italic>true</italic>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Import game despite missing files</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="6" column="0">
|
||||||
<widget class="QLabel" name="import_button_label">
|
<widget class="QLabel" name="import_button_label">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string notr="true">Error</string>
|
<string notr="true">Error</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="5" column="1">
|
<item row="6" column="1">
|
||||||
<layout class="QHBoxLayout" name="button_info_layout">
|
<layout class="QHBoxLayout" name="button_info_layout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="import_button">
|
<widget class="QPushButton" name="import_button">
|
||||||
|
@ -99,24 +118,38 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="4" column="0">
|
<item row="2" column="0">
|
||||||
<widget class="QLabel" name="import_force_label">
|
<widget class="QLabel" name="platform_label">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Force import</string>
|
<string>Platform</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="4" column="1">
|
<item row="2" column="1">
|
||||||
<widget class="QCheckBox" name="import_force_check">
|
<layout class="QHBoxLayout" name="platform_layout">
|
||||||
<property name="font">
|
<item>
|
||||||
<font>
|
<widget class="QComboBox" name="platform_combo">
|
||||||
<italic>true</italic>
|
<property name="sizePolicy">
|
||||||
</font>
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
</property>
|
<horstretch>0</horstretch>
|
||||||
<property name="text">
|
<verstretch>0</verstretch>
|
||||||
<string>Import game despite missing files</string>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="platform_tooltip">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<italic>true</italic>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Select the native platform of the game</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
# Form implementation generated from reading ui file 'rare/ui/components/tabs/settings/legendary.ui'
|
# Form implementation generated from reading ui file 'rare/ui/components/tabs/settings/legendary.ui'
|
||||||
#
|
#
|
||||||
# Created by: PyQt5 UI code generator 5.15.7
|
# Created by: PyQt5 UI code generator 5.15.10
|
||||||
#
|
#
|
||||||
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
|
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
|
||||||
# run again. Do not edit this file unless you know what you are doing.
|
# run again. Do not edit this file unless you know what you are doing.
|
||||||
|
@ -14,7 +14,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets
|
||||||
class Ui_LegendarySettings(object):
|
class Ui_LegendarySettings(object):
|
||||||
def setupUi(self, LegendarySettings):
|
def setupUi(self, LegendarySettings):
|
||||||
LegendarySettings.setObjectName("LegendarySettings")
|
LegendarySettings.setObjectName("LegendarySettings")
|
||||||
LegendarySettings.resize(595, 334)
|
LegendarySettings.resize(681, 456)
|
||||||
LegendarySettings.setWindowTitle("LegendarySettings")
|
LegendarySettings.setWindowTitle("LegendarySettings")
|
||||||
self.legendary_layout = QtWidgets.QHBoxLayout(LegendarySettings)
|
self.legendary_layout = QtWidgets.QHBoxLayout(LegendarySettings)
|
||||||
self.legendary_layout.setObjectName("legendary_layout")
|
self.legendary_layout.setObjectName("legendary_layout")
|
||||||
|
@ -125,21 +125,30 @@ class Ui_LegendarySettings(object):
|
||||||
self.clean_button = QtWidgets.QPushButton(self.cleanup_group)
|
self.clean_button = QtWidgets.QPushButton(self.cleanup_group)
|
||||||
self.clean_button.setObjectName("clean_button")
|
self.clean_button.setObjectName("clean_button")
|
||||||
self.cleanup_layout.addWidget(self.clean_button)
|
self.cleanup_layout.addWidget(self.clean_button)
|
||||||
self.right_layout.addWidget(self.cleanup_group, 0, QtCore.Qt.AlignTop)
|
self.right_layout.addWidget(self.cleanup_group)
|
||||||
self.meta_group = QtWidgets.QGroupBox(LegendarySettings)
|
self.metadata_group = QtWidgets.QGroupBox(LegendarySettings)
|
||||||
self.meta_group.setObjectName("meta_group")
|
self.metadata_group.setObjectName("metadata_group")
|
||||||
self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.meta_group)
|
self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.metadata_group)
|
||||||
self.verticalLayout_2.setObjectName("verticalLayout_2")
|
self.verticalLayout_2.setObjectName("verticalLayout_2")
|
||||||
self.win32_cb = QtWidgets.QCheckBox(self.meta_group)
|
self.fetch_win32_check = QtWidgets.QCheckBox(self.metadata_group)
|
||||||
self.win32_cb.setObjectName("win32_cb")
|
self.fetch_win32_check.setObjectName("fetch_win32_check")
|
||||||
self.verticalLayout_2.addWidget(self.win32_cb)
|
self.verticalLayout_2.addWidget(self.fetch_win32_check)
|
||||||
self.mac_cb = QtWidgets.QCheckBox(self.meta_group)
|
self.fetch_macos_check = QtWidgets.QCheckBox(self.metadata_group)
|
||||||
self.mac_cb.setObjectName("mac_cb")
|
self.fetch_macos_check.setObjectName("fetch_macos_check")
|
||||||
self.verticalLayout_2.addWidget(self.mac_cb)
|
self.verticalLayout_2.addWidget(self.fetch_macos_check)
|
||||||
self.refresh_game_meta_btn = QtWidgets.QPushButton(self.meta_group)
|
self.fetch_unreal_check = QtWidgets.QCheckBox(self.metadata_group)
|
||||||
self.refresh_game_meta_btn.setObjectName("refresh_game_meta_btn")
|
self.fetch_unreal_check.setObjectName("fetch_unreal_check")
|
||||||
self.verticalLayout_2.addWidget(self.refresh_game_meta_btn)
|
self.verticalLayout_2.addWidget(self.fetch_unreal_check)
|
||||||
self.right_layout.addWidget(self.meta_group)
|
self.metadata_info = QtWidgets.QLabel(self.metadata_group)
|
||||||
|
font = QtGui.QFont()
|
||||||
|
font.setItalic(True)
|
||||||
|
self.metadata_info.setFont(font)
|
||||||
|
self.metadata_info.setObjectName("metadata_info")
|
||||||
|
self.verticalLayout_2.addWidget(self.metadata_info)
|
||||||
|
self.refresh_metadata_button = QtWidgets.QPushButton(self.metadata_group)
|
||||||
|
self.refresh_metadata_button.setObjectName("refresh_metadata_button")
|
||||||
|
self.verticalLayout_2.addWidget(self.refresh_metadata_button)
|
||||||
|
self.right_layout.addWidget(self.metadata_group)
|
||||||
spacerItem1 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
|
spacerItem1 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
|
||||||
self.right_layout.addItem(spacerItem1)
|
self.right_layout.addItem(spacerItem1)
|
||||||
self.legendary_layout.addLayout(self.right_layout)
|
self.legendary_layout.addLayout(self.right_layout)
|
||||||
|
@ -148,11 +157,11 @@ class Ui_LegendarySettings(object):
|
||||||
|
|
||||||
def retranslateUi(self, LegendarySettings):
|
def retranslateUi(self, LegendarySettings):
|
||||||
_translate = QtCore.QCoreApplication.translate
|
_translate = QtCore.QCoreApplication.translate
|
||||||
self.install_dir_group.setTitle(_translate("LegendarySettings", "Default Installation Directory"))
|
self.install_dir_group.setTitle(_translate("LegendarySettings", "Default installation folder"))
|
||||||
self.download_group.setTitle(_translate("LegendarySettings", "Download Settings"))
|
self.download_group.setTitle(_translate("LegendarySettings", "Download settings"))
|
||||||
self.max_workers_label.setText(_translate("LegendarySettings", "Max Workers"))
|
self.max_workers_label.setText(_translate("LegendarySettings", "Max sorkers"))
|
||||||
self.max_workers_info_label.setText(_translate("LegendarySettings", "Less is slower (0: Default)"))
|
self.max_workers_info_label.setText(_translate("LegendarySettings", "Less is slower (0: Default)"))
|
||||||
self.max_memory_label.setText(_translate("LegendarySettings", "Max Shared Memory"))
|
self.max_memory_label.setText(_translate("LegendarySettings", "Max shared memory"))
|
||||||
self.max_memory_spin.setSuffix(_translate("LegendarySettings", "MiB"))
|
self.max_memory_spin.setSuffix(_translate("LegendarySettings", "MiB"))
|
||||||
self.max_memory_info_label.setText(_translate("LegendarySettings", "Less is slower (0: Default)"))
|
self.max_memory_info_label.setText(_translate("LegendarySettings", "Less is slower (0: Default)"))
|
||||||
self.preferred_cdn_label.setText(_translate("LegendarySettings", "Preferred CDN"))
|
self.preferred_cdn_label.setText(_translate("LegendarySettings", "Preferred CDN"))
|
||||||
|
@ -162,10 +171,12 @@ class Ui_LegendarySettings(object):
|
||||||
self.cleanup_group.setTitle(_translate("LegendarySettings", "Cleanup"))
|
self.cleanup_group.setTitle(_translate("LegendarySettings", "Cleanup"))
|
||||||
self.clean_keep_manifests_button.setText(_translate("LegendarySettings", "Clean, but keep manifests"))
|
self.clean_keep_manifests_button.setText(_translate("LegendarySettings", "Clean, but keep manifests"))
|
||||||
self.clean_button.setText(_translate("LegendarySettings", "Remove everything"))
|
self.clean_button.setText(_translate("LegendarySettings", "Remove everything"))
|
||||||
self.meta_group.setTitle(_translate("LegendarySettings", "Game metadata"))
|
self.metadata_group.setTitle(_translate("LegendarySettings", "Platforms"))
|
||||||
self.win32_cb.setText(_translate("LegendarySettings", "Load 32bit data"))
|
self.fetch_win32_check.setText(_translate("LegendarySettings", "Include Win32 games"))
|
||||||
self.mac_cb.setText(_translate("LegendarySettings", "Load MacOS data"))
|
self.fetch_macos_check.setText(_translate("LegendarySettings", "Include macOS games"))
|
||||||
self.refresh_game_meta_btn.setText(_translate("LegendarySettings", "Refresh game meta"))
|
self.fetch_unreal_check.setText(_translate("LegendarySettings", "Include Unreal engine"))
|
||||||
|
self.metadata_info.setText(_translate("LegendarySettings", "Restart Rare to apply"))
|
||||||
|
self.refresh_metadata_button.setText(_translate("LegendarySettings", "Refresh metadata"))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>595</width>
|
<width>681</width>
|
||||||
<height>334</height>
|
<height>456</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
|
@ -19,7 +19,7 @@
|
||||||
<item alignment="Qt::AlignTop">
|
<item alignment="Qt::AlignTop">
|
||||||
<widget class="QGroupBox" name="install_dir_group">
|
<widget class="QGroupBox" name="install_dir_group">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Default Installation Directory</string>
|
<string>Default installation folder</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="alignment">
|
<property name="alignment">
|
||||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||||
|
@ -30,7 +30,7 @@
|
||||||
<item alignment="Qt::AlignTop">
|
<item alignment="Qt::AlignTop">
|
||||||
<widget class="QGroupBox" name="download_group">
|
<widget class="QGroupBox" name="download_group">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Download Settings</string>
|
<string>Download settings</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="alignment">
|
<property name="alignment">
|
||||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||||
|
@ -48,7 +48,7 @@
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Max Workers</string>
|
<string>Max sorkers</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -90,7 +90,7 @@
|
||||||
<item row="1" column="0">
|
<item row="1" column="0">
|
||||||
<widget class="QLabel" name="max_memory_label">
|
<widget class="QLabel" name="max_memory_label">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Max Shared Memory</string>
|
<string>Max shared memory</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -200,7 +200,7 @@
|
||||||
<layout class="QVBoxLayout" name="locale_layout"/>
|
<layout class="QVBoxLayout" name="locale_layout"/>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item alignment="Qt::AlignTop">
|
<item>
|
||||||
<widget class="QGroupBox" name="cleanup_group">
|
<widget class="QGroupBox" name="cleanup_group">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Cleanup</string>
|
<string>Cleanup</string>
|
||||||
|
@ -227,29 +227,48 @@
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="meta_group">
|
<widget class="QGroupBox" name="metadata_group">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Game metadata</string>
|
<string>Platforms</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="win32_cb">
|
<widget class="QCheckBox" name="fetch_win32_check">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Load 32bit data</string>
|
<string>Include Win32 games</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="mac_cb">
|
<widget class="QCheckBox" name="fetch_macos_check">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Load MacOS data</string>
|
<string>Include macOS games</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="refresh_game_meta_btn">
|
<widget class="QCheckBox" name="fetch_unreal_check">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Refresh game meta</string>
|
<string>Include Unreal engine</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="metadata_info">
|
||||||
|
<property name="font">
|
||||||
|
<font>
|
||||||
|
<italic>true</italic>
|
||||||
|
</font>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Restart Rare to apply</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="refresh_metadata_button">
|
||||||
|
<property name="text">
|
||||||
|
<string>Refresh metadata</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
# Form implementation generated from reading ui file 'rare/ui/components/tabs/settings/rare.ui'
|
# Form implementation generated from reading ui file 'rare/ui/components/tabs/settings/rare.ui'
|
||||||
#
|
#
|
||||||
# Created by: PyQt5 UI code generator 5.15.6
|
# Created by: PyQt5 UI code generator 5.15.10
|
||||||
#
|
#
|
||||||
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
|
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
|
||||||
# run again. Do not edit this file unless you know what you are doing.
|
# run again. Do not edit this file unless you know what you are doing.
|
||||||
|
@ -14,7 +14,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets
|
||||||
class Ui_RareSettings(object):
|
class Ui_RareSettings(object):
|
||||||
def setupUi(self, RareSettings):
|
def setupUi(self, RareSettings):
|
||||||
RareSettings.setObjectName("RareSettings")
|
RareSettings.setObjectName("RareSettings")
|
||||||
RareSettings.resize(517, 434)
|
RareSettings.resize(623, 428)
|
||||||
RareSettings.setWindowTitle("RareSettings")
|
RareSettings.setWindowTitle("RareSettings")
|
||||||
self.rare_layout = QtWidgets.QHBoxLayout(RareSettings)
|
self.rare_layout = QtWidgets.QHBoxLayout(RareSettings)
|
||||||
self.rare_layout.setObjectName("rare_layout")
|
self.rare_layout.setObjectName("rare_layout")
|
||||||
|
@ -148,25 +148,25 @@ class Ui_RareSettings(object):
|
||||||
_translate = QtCore.QCoreApplication.translate
|
_translate = QtCore.QCoreApplication.translate
|
||||||
self.interface_group.setTitle(_translate("RareSettings", "Interface"))
|
self.interface_group.setTitle(_translate("RareSettings", "Interface"))
|
||||||
self.lang_label.setText(_translate("RareSettings", "Language"))
|
self.lang_label.setText(_translate("RareSettings", "Language"))
|
||||||
self.color_label.setText(_translate("RareSettings", "Color Scheme"))
|
self.color_label.setText(_translate("RareSettings", "Color scheme"))
|
||||||
self.color_select.setItemText(0, _translate("RareSettings", "None"))
|
self.color_select.setItemText(0, _translate("RareSettings", "None"))
|
||||||
self.style_label.setText(_translate("RareSettings", "Style Sheet"))
|
self.style_label.setText(_translate("RareSettings", "Style sheet"))
|
||||||
self.style_select.setItemText(0, _translate("RareSettings", "None"))
|
self.style_select.setItemText(0, _translate("RareSettings", "None"))
|
||||||
self.interface_info.setText(_translate("RareSettings", "Restart Rare to apply."))
|
self.interface_info.setText(_translate("RareSettings", "Restart Rare to apply changes."))
|
||||||
self.settings_group.setTitle(_translate("RareSettings", "Behavior"))
|
self.settings_group.setTitle(_translate("RareSettings", "Behavior"))
|
||||||
self.save_size.setText(_translate("RareSettings", "Restore window size on application startup"))
|
self.save_size.setText(_translate("RareSettings", "Restore window size on application startup"))
|
||||||
self.notification.setText(_translate("RareSettings", "Show notification on download completion"))
|
self.notification.setText(_translate("RareSettings", "Show notifications when downloads complete"))
|
||||||
self.log_games.setText(_translate("RareSettings", "Show console for game debug"))
|
self.log_games.setText(_translate("RareSettings", "Show console windows when launching games"))
|
||||||
self.sys_tray.setText(_translate("RareSettings", "Exit to System tray"))
|
self.sys_tray.setText(_translate("RareSettings", "Exit to system tray"))
|
||||||
self.auto_update.setText(_translate("RareSettings", "Update games on application startup"))
|
self.auto_update.setText(_translate("RareSettings", "Queue game updates on application startup"))
|
||||||
self.confirm_start.setText(_translate("RareSettings", "Confirm game launch"))
|
self.confirm_start.setText(_translate("RareSettings", "Confirm before launching games"))
|
||||||
self.auto_sync_cloud.setText(_translate("RareSettings", "Automatically sync with cloud"))
|
self.auto_sync_cloud.setText(_translate("RareSettings", "Automatically upload/download cloud saves"))
|
||||||
self.log_dir_group.setTitle(_translate("RareSettings", "Logs"))
|
self.log_dir_group.setTitle(_translate("RareSettings", "Logs"))
|
||||||
self.log_dir_open_button.setText(_translate("RareSettings", "Open Log directory"))
|
self.log_dir_open_button.setText(_translate("RareSettings", "Open log folder"))
|
||||||
self.log_dir_clean_button.setText(_translate("RareSettings", "Clean Log directory"))
|
self.log_dir_clean_button.setText(_translate("RareSettings", "Clean log folder"))
|
||||||
self.groupBox.setTitle(_translate("RareSettings", "Shortcuts"))
|
self.groupBox.setTitle(_translate("RareSettings", "Shortcuts"))
|
||||||
self.desktop_link_btn.setText(_translate("RareSettings", "Create Desktop link"))
|
self.desktop_link_btn.setText(_translate("RareSettings", "Create on desktop"))
|
||||||
self.startmenu_link_btn.setText(_translate("RareSettings", "Create start menu link"))
|
self.startmenu_link_btn.setText(_translate("RareSettings", "Create in menu"))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>517</width>
|
<width>623</width>
|
||||||
<height>434</height>
|
<height>428</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
|
@ -51,7 +51,7 @@
|
||||||
<item row="1" column="0">
|
<item row="1" column="0">
|
||||||
<widget class="QLabel" name="color_label">
|
<widget class="QLabel" name="color_label">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Color Scheme</string>
|
<string>Color scheme</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -73,7 +73,7 @@
|
||||||
<item row="2" column="0">
|
<item row="2" column="0">
|
||||||
<widget class="QLabel" name="style_label">
|
<widget class="QLabel" name="style_label">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Style Sheet</string>
|
<string>Style sheet</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -100,7 +100,7 @@
|
||||||
</font>
|
</font>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Restart Rare to apply.</string>
|
<string>Restart Rare to apply changes.</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="wordWrap">
|
<property name="wordWrap">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
|
@ -126,42 +126,42 @@
|
||||||
<item row="4" column="0">
|
<item row="4" column="0">
|
||||||
<widget class="QCheckBox" name="notification">
|
<widget class="QCheckBox" name="notification">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Show notification on download completion</string>
|
<string>Show notifications when downloads complete</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="6" column="0">
|
<item row="6" column="0">
|
||||||
<widget class="QCheckBox" name="log_games">
|
<widget class="QCheckBox" name="log_games">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Show console for game debug</string>
|
<string>Show console windows when launching games</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QCheckBox" name="sys_tray">
|
<widget class="QCheckBox" name="sys_tray">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Exit to System tray</string>
|
<string>Exit to system tray</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0">
|
<item row="1" column="0">
|
||||||
<widget class="QCheckBox" name="auto_update">
|
<widget class="QCheckBox" name="auto_update">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Update games on application startup</string>
|
<string>Queue game updates on application startup</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0">
|
<item row="2" column="0">
|
||||||
<widget class="QCheckBox" name="confirm_start">
|
<widget class="QCheckBox" name="confirm_start">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Confirm game launch</string>
|
<string>Confirm before launching games</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="0">
|
<item row="3" column="0">
|
||||||
<widget class="QCheckBox" name="auto_sync_cloud">
|
<widget class="QCheckBox" name="auto_sync_cloud">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Automatically sync with cloud</string>
|
<string>Automatically upload/download cloud saves</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -207,14 +207,14 @@
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="log_dir_open_button">
|
<widget class="QPushButton" name="log_dir_open_button">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Open Log directory</string>
|
<string>Open log folder</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="log_dir_clean_button">
|
<widget class="QPushButton" name="log_dir_clean_button">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Clean Log directory</string>
|
<string>Clean log folder</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -246,14 +246,14 @@
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="desktop_link_btn">
|
<widget class="QPushButton" name="desktop_link_btn">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Create Desktop link</string>
|
<string>Create on desktop</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="startmenu_link_btn">
|
<widget class="QPushButton" name="startmenu_link_btn">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Create start menu link</string>
|
<string>Create in menu</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
|
@ -1,33 +1,55 @@
|
||||||
from typing import Optional
|
from typing import Optional, List, overload
|
||||||
|
|
||||||
from PyQt5.QtCore import (
|
from PyQt5.QtCore import Qt, QRect, QSize, QPoint
|
||||||
Qt,
|
from PyQt5.QtWidgets import QLayout, QStyle, QSizePolicy, QLayoutItem, QWidget
|
||||||
QRect,
|
|
||||||
QSize,
|
|
||||||
QPoint,
|
|
||||||
)
|
|
||||||
from PyQt5.QtWidgets import (
|
|
||||||
QLayout,
|
|
||||||
QStyle,
|
|
||||||
QSizePolicy,
|
|
||||||
QLayoutItem,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class FlowLayout(QLayout):
|
class FlowLayout(QLayout):
|
||||||
def __init__(self, parent=None, margin=-1, hspacing=-1, vspacing=-1):
|
def __init__(self, parent=None):
|
||||||
super(FlowLayout, self).__init__(parent)
|
super(FlowLayout, self).__init__(parent)
|
||||||
self._hspacing = hspacing
|
|
||||||
self._vspacing = vspacing
|
|
||||||
self._items = []
|
|
||||||
self.setContentsMargins(margin, margin, margin, margin)
|
|
||||||
self.setObjectName(type(self).__name__)
|
self.setObjectName(type(self).__name__)
|
||||||
|
self._hspacing = -1
|
||||||
|
self._vspacing = -1
|
||||||
|
self._items: List[QLayoutItem] = []
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
del self._items[:]
|
del self._items[:]
|
||||||
|
|
||||||
|
@overload
|
||||||
|
def indexOf(self, a0: QWidget) -> int:
|
||||||
|
try:
|
||||||
|
return next(idx for idx, item in enumerate(self._items) if item.widget() is a0)
|
||||||
|
except:
|
||||||
|
return -1
|
||||||
|
|
||||||
|
def indexOf(self, a0: QLayoutItem) -> int:
|
||||||
|
try:
|
||||||
|
return self._items.index(a0)
|
||||||
|
except:
|
||||||
|
return -1
|
||||||
|
|
||||||
def addItem(self, a0: QLayoutItem) -> None:
|
def addItem(self, a0: QLayoutItem) -> None:
|
||||||
self._items.append(a0)
|
self._items.append(a0)
|
||||||
|
self.invalidate()
|
||||||
|
|
||||||
|
def removeItem(self, a0: QLayoutItem) -> None:
|
||||||
|
self._items.remove(a0)
|
||||||
|
self.invalidate()
|
||||||
|
|
||||||
|
def spacing(self) -> int:
|
||||||
|
hspacing = self.horizontalSpacing()
|
||||||
|
if hspacing == self.verticalSpacing():
|
||||||
|
return hspacing
|
||||||
|
else:
|
||||||
|
return -1
|
||||||
|
|
||||||
|
def setSpacing(self, a0: int) -> None:
|
||||||
|
self._hspacing = self._vspacing = a0
|
||||||
|
self.invalidate()
|
||||||
|
|
||||||
|
def setHorizontalSpacing(self, a0: int) -> None:
|
||||||
|
self._hspacing = a0
|
||||||
|
self.invalidate()
|
||||||
|
|
||||||
def horizontalSpacing(self):
|
def horizontalSpacing(self):
|
||||||
if self._hspacing >= 0:
|
if self._hspacing >= 0:
|
||||||
|
@ -35,6 +57,10 @@ class FlowLayout(QLayout):
|
||||||
else:
|
else:
|
||||||
return self.smartSpacing(QStyle.PM_LayoutHorizontalSpacing)
|
return self.smartSpacing(QStyle.PM_LayoutHorizontalSpacing)
|
||||||
|
|
||||||
|
def setVerticalSpacing(self, a0: int) -> None:
|
||||||
|
self._vspacing = a0
|
||||||
|
self.invalidate()
|
||||||
|
|
||||||
def verticalSpacing(self):
|
def verticalSpacing(self):
|
||||||
if self._vspacing >= 0:
|
if self._vspacing >= 0:
|
||||||
return self._vspacing
|
return self._vspacing
|
||||||
|
@ -51,11 +77,14 @@ class FlowLayout(QLayout):
|
||||||
|
|
||||||
def takeAt(self, index: int) -> Optional[QLayoutItem]:
|
def takeAt(self, index: int) -> Optional[QLayoutItem]:
|
||||||
if 0 <= index < len(self._items):
|
if 0 <= index < len(self._items):
|
||||||
return self._items.pop(index)
|
item = self._items.pop(index)
|
||||||
|
self.invalidate()
|
||||||
|
return item
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def expandingDirections(self) -> Qt.Orientations:
|
def expandingDirections(self) -> Qt.Orientations:
|
||||||
return Qt.Horizontal | Qt.Vertical
|
return Qt.Orientations(Qt.Orientation(0))
|
||||||
|
# return Qt.Horizontal | Qt.Vertical
|
||||||
|
|
||||||
def hasHeightForWidth(self) -> bool:
|
def hasHeightForWidth(self) -> bool:
|
||||||
return True
|
return True
|
||||||
|
@ -93,8 +122,6 @@ class FlowLayout(QLayout):
|
||||||
if item.isEmpty():
|
if item.isEmpty():
|
||||||
continue
|
continue
|
||||||
widget = item.widget()
|
widget = item.widget()
|
||||||
if not widget.isVisible():
|
|
||||||
continue
|
|
||||||
hspace = self.horizontalSpacing()
|
hspace = self.horizontalSpacing()
|
||||||
if hspace == -1:
|
if hspace == -1:
|
||||||
hspace = widget.style().layoutSpacing(
|
hspace = widget.style().layoutSpacing(
|
||||||
|
|
|
@ -4,7 +4,6 @@ from logging import getLogger
|
||||||
from typing import Callable, Tuple, Optional, Dict, List
|
from typing import Callable, Tuple, Optional, Dict, List
|
||||||
|
|
||||||
from PyQt5.QtCore import (
|
from PyQt5.QtCore import (
|
||||||
Qt,
|
|
||||||
QSize,
|
QSize,
|
||||||
pyqtSignal,
|
pyqtSignal,
|
||||||
QFileInfo,
|
QFileInfo,
|
||||||
|
@ -135,7 +134,8 @@ class IndicatorLineEdit(QWidget):
|
||||||
# Add line_edit
|
# Add line_edit
|
||||||
self.line_edit = QLineEdit(self)
|
self.line_edit = QLineEdit(self)
|
||||||
self.line_edit.setObjectName(f"{type(self).__name__}Edit")
|
self.line_edit.setObjectName(f"{type(self).__name__}Edit")
|
||||||
self.line_edit.setPlaceholderText(placeholder if placeholder else self.tr("Default"))
|
self.line_edit.setPlaceholderText(placeholder if placeholder else self.tr("Use global/default setting"))
|
||||||
|
self.line_edit.setToolTip(placeholder if placeholder else "")
|
||||||
self.line_edit.setSizePolicy(horiz_policy, QSizePolicy.Fixed)
|
self.line_edit.setSizePolicy(horiz_policy, QSizePolicy.Fixed)
|
||||||
# Add completer
|
# Add completer
|
||||||
self.setCompleter(completer)
|
self.setCompleter(completer)
|
||||||
|
|
|
@ -1,23 +1,18 @@
|
||||||
from typing import Callable
|
from typing import Callable
|
||||||
|
|
||||||
from PyQt5.QtCore import (
|
from PyQt5.QtCore import Qt, QRect, QPoint
|
||||||
Qt,
|
from PyQt5.QtWidgets import QSizePolicy
|
||||||
QRect,
|
|
||||||
QPoint,
|
|
||||||
)
|
|
||||||
from PyQt5.QtWidgets import (
|
|
||||||
QSizePolicy,
|
|
||||||
)
|
|
||||||
|
|
||||||
from .flow_layout import FlowLayout
|
from .flow_layout import FlowLayout
|
||||||
|
|
||||||
|
|
||||||
class LibraryLayout(FlowLayout):
|
class LibraryLayout(FlowLayout):
|
||||||
def __init__(self, parent=None, margin=6, spacing=11):
|
def __init__(self, parent=None):
|
||||||
super(LibraryLayout, self).__init__(parent=parent, margin=margin, hspacing=spacing, vspacing=spacing)
|
super(LibraryLayout, self).__init__(parent)
|
||||||
|
|
||||||
def expandingDirections(self) -> Qt.Orientations:
|
def expandingDirections(self) -> Qt.Orientations:
|
||||||
return Qt.Horizontal | Qt.Vertical
|
return Qt.Orientations(Qt.Orientation(0))
|
||||||
|
# return Qt.Horizontal | Qt.Vertical
|
||||||
|
|
||||||
def setGeometry(self, a0: QRect) -> None:
|
def setGeometry(self, a0: QRect) -> None:
|
||||||
super(FlowLayout, self).setGeometry(a0)
|
super(FlowLayout, self).setGeometry(a0)
|
||||||
|
@ -127,4 +122,4 @@ class LibraryLayout(FlowLayout):
|
||||||
|
|
||||||
def sort(self, key: Callable, reverse=False) -> None:
|
def sort(self, key: Callable, reverse=False) -> None:
|
||||||
self._items.sort(key=key, reverse=reverse)
|
self._items.sort(key=key, reverse=reverse)
|
||||||
self.setGeometry(self.parent().contentsRect())
|
self.setGeometry(self.parent().contentsRect().adjusted(*self.parent().getContentsMargins()))
|
||||||
|
|
Loading…
Reference in a new issue