commit
2803319373
|
@ -20,7 +20,7 @@ AppDir:
|
|||
id: io.github.dummerle.rare
|
||||
name: Rare
|
||||
icon: Rare
|
||||
version: 1.10.7
|
||||
version: 1.10.9
|
||||
exec: usr/bin/python3
|
||||
exec_args: $APPDIR/usr/src/rare/main.py $@
|
||||
apt:
|
||||
|
|
|
@ -12,7 +12,7 @@ force-exclude = '''
|
|||
|
||||
[tool.poetry]
|
||||
name = "rare"
|
||||
version = "1.10.7"
|
||||
version = "1.10.9"
|
||||
description = "A GUI for Legendary"
|
||||
authors = ["Dummerle"]
|
||||
license = "GPL3"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
__version__ = "1.10.7"
|
||||
__version__ = "1.10.9"
|
||||
__codename__ = "Garlic Crab"
|
||||
|
||||
# For PyCharm profiler
|
||||
|
|
|
@ -45,8 +45,6 @@ class Rare(RareApp):
|
|||
self.signals = RareCore.instance().signals()
|
||||
self.core = RareCore.instance().core()
|
||||
|
||||
config_helper.init_config_handler(self.core)
|
||||
|
||||
lang = self.settings.value("language", self.core.language_code, type=str)
|
||||
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.setWindowTitle(f'{header} "{self.rgame.app_title}" - {QCoreApplication.instance().applicationName()}')
|
||||
|
||||
if not self.options.base_path:
|
||||
self.options.base_path = self.core.lgd.config.get(
|
||||
"Legendary", "install_dir", fallback=os.path.expanduser("~/legendary")
|
||||
)
|
||||
if options.base_path:
|
||||
base_path = options.base_path
|
||||
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(
|
||||
path=self.options.base_path,
|
||||
path=base_path,
|
||||
file_mode=QFileDialog.DirectoryOnly,
|
||||
edit_func=self.option_changed,
|
||||
save_func=self.save_install_edit,
|
||||
|
@ -90,36 +92,24 @@ class InstallDialog(QDialog):
|
|||
QFormLayout.FieldRole, self.install_dir_edit
|
||||
)
|
||||
|
||||
if self.options.update:
|
||||
self.ui.install_dir_label.setEnabled(False)
|
||||
self.install_dir_edit.setEnabled(False)
|
||||
self.ui.shortcut_label.setEnabled(False)
|
||||
self.ui.shortcut_check.setEnabled(False)
|
||||
else:
|
||||
self.ui.shortcut_check.setChecked(QSettings().value("create_shortcut", True, bool))
|
||||
self.install_dir_edit.setDisabled(rgame.is_installed)
|
||||
self.ui.install_dir_label.setDisabled(rgame.is_installed)
|
||||
self.ui.shortcut_label.setDisabled(rgame.is_installed)
|
||||
self.ui.shortcut_check.setDisabled(rgame.is_installed)
|
||||
self.ui.shortcut_check.setChecked(not rgame.is_installed and QSettings().value("create_shortcut", True, bool))
|
||||
|
||||
self.error_box()
|
||||
|
||||
platforms = self.rgame.platforms
|
||||
self.ui.platform_combo.addItems(reversed(platforms))
|
||||
self.ui.platform_combo.currentIndexChanged.connect(lambda: self.option_changed(None))
|
||||
self.ui.platform_combo.currentIndexChanged.connect(lambda: self.error_box())
|
||||
self.ui.platform_combo.currentIndexChanged.connect(
|
||||
lambda i: 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(
|
||||
self.ui.platform_combo.itemText(i)
|
||||
),
|
||||
)
|
||||
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.ui.platform_combo.addItems(reversed(rgame.platforms))
|
||||
combo_text = rgame.igame.platform if rgame.is_installed else rgame.default_platform
|
||||
self.ui.platform_combo.setCurrentIndex(self.ui.platform_combo.findText(combo_text))
|
||||
self.ui.platform_combo.currentIndexChanged.connect(lambda i: self.option_changed(None))
|
||||
self.ui.platform_combo.currentIndexChanged.connect(self.check_incompatible_platform)
|
||||
self.ui.platform_combo.currentIndexChanged.connect(self.reset_install_dir)
|
||||
self.ui.platform_combo.currentIndexChanged.connect(self.reset_sdl_list)
|
||||
|
||||
self.ui.platform_label.setDisabled(rgame.is_installed)
|
||||
self.ui.platform_combo.setDisabled(rgame.is_installed)
|
||||
|
||||
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)
|
||||
|
@ -139,7 +129,10 @@ class InstallDialog(QDialog):
|
|||
|
||||
self.selectable_checks: List[TagCheckBox] = []
|
||||
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)
|
||||
|
||||
|
@ -155,9 +148,10 @@ class InstallDialog(QDialog):
|
|||
self.selectable.setEnabled(False)
|
||||
|
||||
if pf.system() == "Darwin":
|
||||
self.ui.shortcut_label.setDisabled(True)
|
||||
self.ui.shortcut_check.setDisabled(True)
|
||||
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_check.setEnabled(False)
|
||||
|
@ -190,8 +184,16 @@ class InstallDialog(QDialog):
|
|||
self.__on_verify()
|
||||
self.show()
|
||||
|
||||
@pyqtSlot(str)
|
||||
def setup_sdl_list(self, platform="Windows"):
|
||||
@pyqtSlot(int)
|
||||
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:
|
||||
cb.disconnect()
|
||||
cb.deleteLater()
|
||||
|
@ -223,8 +225,19 @@ class InstallDialog(QDialog):
|
|||
else:
|
||||
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):
|
||||
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.shared_memory = self.advanced.ui.max_memory_spin.value()
|
||||
self.options.order_opt = self.advanced.ui.dl_optimizations_check.isChecked()
|
||||
|
|
|
@ -346,5 +346,5 @@ class DownloadsTab(QWidget):
|
|||
@pyqtSlot(RareGame, bool, str)
|
||||
def __on_uninstall_worker_result(self, rgame: RareGame, success: bool, message: str):
|
||||
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
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
from logging import getLogger
|
||||
|
||||
from PyQt5.QtCore import QSettings, Qt, pyqtSlot
|
||||
from PyQt5.QtGui import QShowEvent
|
||||
from PyQt5.QtWidgets import QStackedWidget, QVBoxLayout, QWidget, QScrollArea, QFrame
|
||||
|
||||
from rare.models.game import RareGame
|
||||
|
@ -33,8 +34,6 @@ class GamesTab(QStackedWidget):
|
|||
self.image_manager = ImageManagerSingleton()
|
||||
self.settings = QSettings()
|
||||
|
||||
self.active_filter: int = 0
|
||||
|
||||
self.games_page = QWidget(parent=self)
|
||||
games_page_layout = QVBoxLayout(self.games_page)
|
||||
self.addWidget(self.games_page)
|
||||
|
@ -69,6 +68,7 @@ class GamesTab(QStackedWidget):
|
|||
|
||||
self.icon_view = QWidget(self.icon_view_scroll)
|
||||
icon_view_layout = LibraryLayout(self.icon_view)
|
||||
icon_view_layout.setSpacing(9)
|
||||
icon_view_layout.setContentsMargins(0, 13, 0, 13)
|
||||
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.view.toggled.connect(self.toggle_view)
|
||||
|
||||
f = self.settings.value("filter", 0, int)
|
||||
if f >= len(self.head_bar.available_filters):
|
||||
f = 0
|
||||
self.active_filter = self.head_bar.available_filters[f]
|
||||
self.active_filter: str = self.head_bar.filter.currentData(Qt.UserRole)
|
||||
|
||||
# signals
|
||||
self.signals.game.installed.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.init = False
|
||||
return super().showEvent(a0)
|
||||
|
||||
@pyqtSlot()
|
||||
def scroll_to_top(self):
|
||||
|
@ -149,7 +153,7 @@ class GamesTab(QStackedWidget):
|
|||
for rgame in self.rcore.games:
|
||||
icon_widget, list_widget = self.add_library_widget(rgame)
|
||||
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
|
||||
self.icon_view.layout().addWidget(icon_widget)
|
||||
self.list_view.layout().addWidget(list_widget)
|
||||
|
@ -160,8 +164,7 @@ class GamesTab(QStackedWidget):
|
|||
try:
|
||||
icon_widget, list_widget = self.library_controller.add_game(rgame)
|
||||
except Exception as e:
|
||||
raise e
|
||||
logger.error(f"{rgame.app_name} is broken. Don't add it to game list: {e}")
|
||||
logger.error("Could not add widget for %s to library: %s", rgame.app_name, e)
|
||||
return None, None
|
||||
icon_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("")
|
||||
QMessageBox.warning(
|
||||
self,
|
||||
self.tr("Error - {}").format(self.rgame.title),
|
||||
self.tr("Error - {}").format(self.rgame.app_title),
|
||||
self.tr(
|
||||
"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
|
||||
if not path:
|
||||
|
@ -217,7 +217,7 @@ class CloudSaves(QWidget, SideTabContents):
|
|||
|
||||
self.rgame = rgame
|
||||
|
||||
self.set_title.emit(rgame.title)
|
||||
self.set_title.emit(rgame.app_title)
|
||||
rgame.signals.widget.update.connect(self.__update_widget)
|
||||
|
||||
self.__update_widget()
|
||||
|
|
|
@ -121,7 +121,7 @@ class GameInfo(QWidget, SideTabContents):
|
|||
if not os.path.exists(repair_file):
|
||||
QMessageBox.warning(
|
||||
self,
|
||||
self.tr("Error - {}").format(self.rgame.title),
|
||||
self.tr("Error - {}").format(self.rgame.app_title),
|
||||
self.tr(
|
||||
"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:
|
||||
ans = QMessageBox.question(
|
||||
self,
|
||||
self.tr("Repair and update? - {}").format(self.rgame.title),
|
||||
self.tr("Repair and update? - {}").format(self.rgame.app_title),
|
||||
self.tr(
|
||||
"There is an update for <b>{}</b> from <b>{}</b> to <b>{}</b>. "
|
||||
"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
|
||||
rgame.repair(repair_and_update=ans)
|
||||
|
||||
|
@ -147,7 +147,7 @@ class GameInfo(QWidget, SideTabContents):
|
|||
def __on_worker_error(self, rgame: RareGame, message: str):
|
||||
QMessageBox.warning(
|
||||
self,
|
||||
self.tr("Error - {}").format(rgame.title),
|
||||
self.tr("Error - {}").format(rgame.app_title),
|
||||
message
|
||||
)
|
||||
|
||||
|
@ -155,11 +155,11 @@ class GameInfo(QWidget, SideTabContents):
|
|||
def __on_verify(self):
|
||||
""" This method is to be called from the button only """
|
||||
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(
|
||||
self,
|
||||
self.tr("Error - {}").format(self.rgame.title),
|
||||
self.tr("Installation path for <b>{}</b> does not exist. Cannot continue.").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.app_title),
|
||||
)
|
||||
return
|
||||
self.verify_game(self.rgame)
|
||||
|
@ -184,18 +184,18 @@ class GameInfo(QWidget, SideTabContents):
|
|||
if success:
|
||||
QMessageBox.information(
|
||||
self,
|
||||
self.tr("Summary - {}").format(rgame.title),
|
||||
self.tr("Summary - {}").format(rgame.app_title),
|
||||
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:
|
||||
ans = QMessageBox.question(
|
||||
self,
|
||||
self.tr("Summary - {}").format(rgame.title),
|
||||
self.tr("Summary - {}").format(rgame.app_title),
|
||||
self.tr(
|
||||
"<b>{}</b> failed verification, <b>{}</b> file(s) corrupted, <b>{}</b> file(s) are missing. "
|
||||
"Do you want to repair them?"
|
||||
).format(rgame.title, failed, missing),
|
||||
).format(rgame.app_title, failed, missing),
|
||||
QMessageBox.Yes | QMessageBox.No,
|
||||
QMessageBox.Yes,
|
||||
)
|
||||
|
@ -216,7 +216,7 @@ class GameInfo(QWidget, SideTabContents):
|
|||
if os.path.basename(self.rgame.install_path) in os.path.basename(item):
|
||||
ans = QMessageBox.question(
|
||||
self,
|
||||
self.tr("Move game? - {}").format(self.rgame.title),
|
||||
self.tr("Move game? - {}").format(self.rgame.app_title),
|
||||
self.tr(
|
||||
"Destination <b>{}</b> already exists. "
|
||||
"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):
|
||||
QMessageBox.information(
|
||||
self,
|
||||
self.tr("Summary - {}").format(rgame.title),
|
||||
self.tr("<b>{}</b> successfully moved to <b>{}<b>.").format(rgame.title, dst_path),
|
||||
self.tr("Summary - {}").format(rgame.app_title),
|
||||
self.tr("<b>{}</b> successfully moved to <b>{}<b>.").format(rgame.app_title, dst_path),
|
||||
)
|
||||
|
||||
@pyqtSlot()
|
||||
|
@ -284,7 +284,9 @@ class GameInfo(QWidget, SideTabContents):
|
|||
)
|
||||
|
||||
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(
|
||||
|
|
|
@ -38,15 +38,15 @@ class LibraryWidgetController(QObject):
|
|||
elif "hidden" in widget.rgame.metadata.tags:
|
||||
visible = False
|
||||
elif filter_name == "installed":
|
||||
visible = widget.rgame.is_installed
|
||||
visible = widget.rgame.is_installed and not widget.rgame.is_unreal
|
||||
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":
|
||||
visible = widget.rgame.is_win32
|
||||
visible = widget.rgame.is_win32 and not widget.rgame.is_unreal
|
||||
elif filter_name == "mac":
|
||||
visible = widget.rgame.is_mac
|
||||
visible = widget.rgame.is_mac and not widget.rgame.is_unreal
|
||||
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":
|
||||
visible = True
|
||||
elif filter_name == "all":
|
||||
|
|
|
@ -15,7 +15,7 @@ class IconGameWidget(GameWidget):
|
|||
def __init__(self, rgame: RareGame, parent=None):
|
||||
super().__init__(rgame, parent)
|
||||
self.setObjectName(f"{rgame.app_name}")
|
||||
self.setFixedSize(ImageSize.Display)
|
||||
self.setFixedSize(ImageSize.Library)
|
||||
self.ui = IconWidget()
|
||||
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 (
|
||||
QLabel,
|
||||
QPushButton,
|
||||
|
@ -22,45 +24,28 @@ class GameListHeadBar(QWidget):
|
|||
def __init__(self, parent=None):
|
||||
super(GameListHeadBar, self).__init__(parent=parent)
|
||||
self.rcore = RareCore.instance()
|
||||
self.settings = QSettings()
|
||||
self.settings = QSettings(self)
|
||||
|
||||
self.filter = QComboBox()
|
||||
self.filter.addItems(
|
||||
[
|
||||
self.tr("All games"),
|
||||
self.tr("Installed only"),
|
||||
self.tr("Offline Games"),
|
||||
# self.tr("Hidden")
|
||||
]
|
||||
)
|
||||
|
||||
self.available_filters = [
|
||||
"all",
|
||||
"installed",
|
||||
"offline",
|
||||
# "hidden"
|
||||
]
|
||||
self.filter = QComboBox(self)
|
||||
self.filter.addItem(self.tr("All games"), "all")
|
||||
self.filter.addItem(self.tr("Installed"), "installed")
|
||||
self.filter.addItem(self.tr("Offline"), "offline")
|
||||
# self.filter.addItem(self.tr("Hidden"), "hidden")
|
||||
if self.rcore.bit32_games:
|
||||
self.filter.addItem(self.tr("32 Bit Games"))
|
||||
self.available_filters.append("32bit")
|
||||
|
||||
self.filter.addItem(self.tr("32bit games"), "32bit")
|
||||
if self.rcore.mac_games:
|
||||
self.filter.addItem(self.tr("Mac games"))
|
||||
self.available_filters.append("mac")
|
||||
|
||||
self.filter.addItem(self.tr("macOS games"), "mac")
|
||||
if self.rcore.origin_games:
|
||||
self.filter.addItem(self.tr("Exclude Origin"))
|
||||
self.available_filters.append("installable")
|
||||
|
||||
self.filter.addItem(self.tr("Include Unreal Engine"))
|
||||
self.available_filters.append("include_ue")
|
||||
self.filter.addItem(self.tr("Exclude Origin"), "installable")
|
||||
self.filter.addItem(self.tr("Include Unreal"), "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:
|
||||
self.filter.setCurrentIndex(self.settings.value("filter", 0, int))
|
||||
self.filter.setCurrentIndex(self.settings.value("library_filter", filter_index, int))
|
||||
except TypeError:
|
||||
self.settings.setValue("filter", 0)
|
||||
self.filter.setCurrentIndex(0)
|
||||
|
||||
self.settings.setValue("library_filter", filter_index)
|
||||
self.filter.setCurrentIndex(filter_index)
|
||||
self.filter.currentIndexChanged.connect(self.filter_changed)
|
||||
|
||||
integrations_menu = QMenu(self)
|
||||
|
@ -139,6 +124,6 @@ class GameListHeadBar(QWidget):
|
|||
self.rcore.fetch()
|
||||
|
||||
@pyqtSlot(int)
|
||||
def filter_changed(self, i: int):
|
||||
self.filterChanged.emit(self.available_filters[i])
|
||||
self.settings.setValue("filter", i)
|
||||
def filter_changed(self, index: int):
|
||||
self.filterChanged.emit(self.filter.itemData(index, Qt.UserRole))
|
||||
self.settings.setValue("library_filter", index)
|
||||
|
|
|
@ -213,9 +213,7 @@ class EOSGroup(QGroupBox, Ui_EosWidget):
|
|||
self.enabled_cb.setChecked(enabled)
|
||||
|
||||
def install_overlay(self, update=False):
|
||||
base_path = os.path.join(
|
||||
self.core.lgd.config.get("Legendary", "install_dir", fallback=os.path.expanduser("~/legendary")),".overlay"
|
||||
)
|
||||
base_path = os.path.join(self.core.get_default_install_dir(), ".overlay")
|
||||
if update:
|
||||
if not self.overlay:
|
||||
self.overlay_stack.setCurrentIndex(1)
|
||||
|
|
|
@ -72,8 +72,10 @@ class ImportWorker(QRunnable):
|
|||
|
||||
def __init__(
|
||||
self,
|
||||
core: LegendaryCore, path: str,
|
||||
core: LegendaryCore,
|
||||
path: str,
|
||||
app_name: str = None,
|
||||
platform: Optional[str] = None,
|
||||
import_folder: bool = False,
|
||||
import_dlcs: bool = False,
|
||||
import_force: bool = False
|
||||
|
@ -86,6 +88,7 @@ class ImportWorker(QRunnable):
|
|||
self.path = Path(path)
|
||||
self.app_name = app_name
|
||||
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_force = import_force
|
||||
|
||||
|
@ -110,9 +113,13 @@ class ImportWorker(QRunnable):
|
|||
result = ImportedGame(ImportResult.ERROR)
|
||||
result.path = str(path)
|
||||
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_title = app_title = self.core.get_game(app_name).app_title
|
||||
success, message = self.__import_game(path, app_name, app_title)
|
||||
result.app_title = game.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:
|
||||
result.result = ImportResult.FAILED
|
||||
result.message = message
|
||||
|
@ -120,12 +127,13 @@ class ImportWorker(QRunnable):
|
|||
result.result = ImportResult.SUCCESS
|
||||
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)
|
||||
status = LgndrIndirectStatus()
|
||||
args = LgndrImportGameArgs(
|
||||
app_path=str(path),
|
||||
app_name=app_name,
|
||||
platform=platform,
|
||||
disable_check=self.import_force,
|
||||
skip_dlcs=not self.import_dlcs,
|
||||
with_dlcs=self.import_dlcs,
|
||||
|
@ -192,7 +200,7 @@ class ImportGroup(QGroupBox):
|
|||
self.__install_dirs: Set[str] = set()
|
||||
|
||||
self.path_edit = PathEdit(
|
||||
self.core.get_default_install_dir(),
|
||||
self.core.get_default_install_dir(self.core.default_platform),
|
||||
QFileDialog.DirectoryOnly,
|
||||
edit_func=self.path_edit_callback,
|
||||
parent=self,
|
||||
|
@ -206,6 +214,7 @@ class ImportGroup(QGroupBox):
|
|||
self.app_name_edit = IndicatorLineEdit(
|
||||
placeholder=self.tr("Use in case the app name was not found automatically"),
|
||||
edit_func=self.app_name_edit_callback,
|
||||
save_func=self.app_name_save_callback,
|
||||
parent=self,
|
||||
)
|
||||
self.app_name_edit.textChanged.connect(self.app_name_changed)
|
||||
|
@ -247,8 +256,10 @@ class ImportGroup(QGroupBox):
|
|||
|
||||
def set_game(self, app_name: str):
|
||||
if app_name:
|
||||
folder = self.rcore.get_game(app_name).folder_name
|
||||
self.path_edit.setText(os.path.join(self.core.get_default_install_dir(), folder))
|
||||
rgame = self.rcore.get_game(app_name)
|
||||
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)
|
||||
|
||||
def path_edit_callback(self, path) -> Tuple[bool, str, int]:
|
||||
|
@ -279,6 +290,12 @@ class ImportGroup(QGroupBox):
|
|||
else:
|
||||
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)
|
||||
def app_name_changed(self, app_name: str):
|
||||
self.info_label.setText("")
|
||||
|
@ -294,6 +311,14 @@ class ImportGroup(QGroupBox):
|
|||
@pyqtSlot(int)
|
||||
def import_folder_changed(self, state: Qt.CheckState):
|
||||
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_force_check.setCheckState(Qt.Unchecked)
|
||||
self.ui.import_dlcs_check.setEnabled(
|
||||
|
@ -322,10 +347,11 @@ class ImportGroup(QGroupBox):
|
|||
self.worker = ImportWorker(
|
||||
self.core,
|
||||
path,
|
||||
self.app_name_edit.text(),
|
||||
self.ui.import_folder_check.isChecked(),
|
||||
self.ui.import_dlcs_check.isChecked(),
|
||||
self.ui.import_force_check.isChecked()
|
||||
app_name=self.app_name_edit.text(),
|
||||
platform=self.ui.platform_combo.currentText() if not self.ui.import_folder_check.isChecked() else None,
|
||||
import_folder=self.ui.import_folder_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.result.connect(self.__on_import_result)
|
||||
|
|
|
@ -74,7 +74,6 @@ class UbiConnectWorker(Worker):
|
|||
def __init__(self, core: LegendaryCore, ubi_account_id, partner_link_id):
|
||||
super(UbiConnectWorker, self).__init__()
|
||||
self.signals = UbiConnectWorker.Signals()
|
||||
self.setAutoDelete(True)
|
||||
self.core = core
|
||||
self.ubi_account_id = ubi_account_id
|
||||
self.partner_link_id = partner_link_id
|
||||
|
|
|
@ -40,8 +40,10 @@ class DefaultGameSettings(QWidget):
|
|||
|
||||
if platform.system() != "Windows":
|
||||
self.linux_settings = LinuxAppSettings()
|
||||
self.proton_settings = ProtonSettings(self.linux_settings, self.wrapper_settings)
|
||||
self.ui.proton_layout.addWidget(self.proton_settings)
|
||||
if platform.system() != "Darwin":
|
||||
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: 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")
|
||||
if active else self.wrapper_settings.delete_wrapper("mangohud"))
|
||||
self.linux_settings.environ_changed.connect(self.env_vars.reset_model)
|
||||
self.proton_settings.environ_changed.connect(self.env_vars.reset_model)
|
||||
|
||||
else:
|
||||
self.ui.linux_settings_widget.setVisible(False)
|
||||
|
||||
|
@ -77,7 +77,10 @@ class DefaultGameSettings(QWidget):
|
|||
proton = self.wrapper_settings.wrappers.get("proton", "")
|
||||
if proton:
|
||||
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:
|
||||
self.linux_settings.ui.wine_groupbox.setEnabled(False)
|
||||
else:
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import platform
|
||||
import platform as pf
|
||||
import re
|
||||
from logging import getLogger
|
||||
from typing import Tuple
|
||||
from typing import Tuple, List
|
||||
|
||||
from PyQt5.QtCore import QObject, pyqtSignal, QThreadPool, QSettings
|
||||
from PyQt5.QtWidgets import QSizePolicy, QWidget, QFileDialog, QMessageBox
|
||||
|
@ -19,14 +19,21 @@ class RefreshGameMetaWorker(Worker):
|
|||
class Signals(QObject):
|
||||
finished = pyqtSignal()
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self, platforms: List[str], include_unreal: bool):
|
||||
super(RefreshGameMetaWorker, self).__init__()
|
||||
self.signals = RefreshGameMetaWorker.Signals()
|
||||
self.setAutoDelete(True)
|
||||
self.core = LegendaryCoreSingleton()
|
||||
if platforms:
|
||||
self.platforms = platforms
|
||||
else:
|
||||
self.platforms = ["Windows"]
|
||||
self.skip_ue = not include_unreal
|
||||
|
||||
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()
|
||||
|
||||
|
||||
|
@ -34,15 +41,26 @@ class LegendarySettings(QWidget, Ui_LegendarySettings):
|
|||
def __init__(self, parent=None):
|
||||
super(LegendarySettings, self).__init__(parent=parent)
|
||||
self.setupUi(self)
|
||||
self.settings = QSettings()
|
||||
self.settings = QSettings(self)
|
||||
|
||||
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.core.get_default_install_dir(),
|
||||
placeholder=self.tr("Default installation folder for Windows games"),
|
||||
file_mode=QFileDialog.DirectoryOnly,
|
||||
save_func=self.path_save,
|
||||
save_func=self.__win_path_save,
|
||||
)
|
||||
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.win32_cb.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.setChecked(self.settings.value("win32_meta", False, bool))
|
||||
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.mac_cb.stateChanged.connect(lambda: self.settings.setValue("mac_meta", self.mac_cb.isChecked()))
|
||||
self.fetch_macos_check.setChecked(self.settings.value("macos_meta", pf.system() == "Darwin", bool))
|
||||
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_game_meta_btn.setDisabled(True)
|
||||
self.refresh_game_meta_btn.setText(self.tr("Loading"))
|
||||
worker = RefreshGameMetaWorker()
|
||||
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")))
|
||||
self.refresh_metadata_button.clicked.connect(self.refresh_metadata)
|
||||
# FIXME: Disable the button for now because it interferes with RareCore
|
||||
self.refresh_metadata_button.setEnabled(False)
|
||||
self.refresh_metadata_button.setVisible(False)
|
||||
|
||||
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)
|
||||
|
||||
@staticmethod
|
||||
|
@ -120,12 +154,20 @@ class LegendarySettings(QWidget, Ui_LegendarySettings):
|
|||
self.core.lgd.config.remove_option("Legendary", "locale")
|
||||
self.core.lgd.save_config()
|
||||
|
||||
def path_save(self, text: str):
|
||||
self.core.lgd.config["Legendary"]["install_dir"] = text
|
||||
if not text and "install_dir" in self.core.lgd.config["Legendary"].keys():
|
||||
self.core.lgd.config["Legendary"].pop("install_dir")
|
||||
def __mac_path_save(self, text: str) -> None:
|
||||
self.__path_save(text, "mac_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:
|
||||
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()
|
||||
|
||||
def max_worker_save(self, workers: str):
|
||||
|
|
|
@ -82,8 +82,6 @@ class RareSettings(QWidget, Ui_RareSettings):
|
|||
self.style_select.setCurrentIndex(0)
|
||||
self.style_select.currentIndexChanged.connect(self.on_style_select_changed)
|
||||
|
||||
self.interface_info.setVisible(False)
|
||||
|
||||
self.rpc = RPCSettings(self)
|
||||
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.style_select.setDisabled(False)
|
||||
set_color_pallete("")
|
||||
self.interface_info.setVisible(True)
|
||||
|
||||
def on_style_select_changed(self, style):
|
||||
if style:
|
||||
|
@ -215,7 +212,6 @@ class RareSettings(QWidget, Ui_RareSettings):
|
|||
self.settings.setValue("style_sheet", "")
|
||||
self.color_select.setDisabled(False)
|
||||
set_style_sheet("")
|
||||
self.interface_info.setVisible(True)
|
||||
|
||||
def open_dir(self):
|
||||
if platform.system() == "Windows":
|
||||
|
@ -230,7 +226,6 @@ class RareSettings(QWidget, Ui_RareSettings):
|
|||
|
||||
def update_lang(self, i: int):
|
||||
self.settings.setValue("language", languages[i][0])
|
||||
self.interface_info.setVisible(True)
|
||||
|
||||
def init_checkboxes(self, checkboxes):
|
||||
for cb in checkboxes:
|
||||
|
|
|
@ -43,9 +43,9 @@ class LegendaryCLI(LegendaryCLIReal):
|
|||
def unlock_installed(func):
|
||||
@functools.wraps(func)
|
||||
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():
|
||||
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)
|
||||
try:
|
||||
ret = func(self, *args, **kwargs)
|
||||
|
|
|
@ -3,6 +3,7 @@ import json
|
|||
import logging
|
||||
import os
|
||||
from multiprocessing import Queue
|
||||
from sys import platform as sys_platform
|
||||
from uuid import uuid4
|
||||
|
||||
# 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 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.lfs.lgndry import LGDLFS
|
||||
|
||||
legendary.core.DLManager = DLManager
|
||||
legendary.core.LGDLFS = LGDLFS
|
||||
|
@ -30,6 +31,7 @@ class LegendaryCore(LegendaryCoreReal):
|
|||
def __init__(self, *args, **kwargs):
|
||||
super(LegendaryCore, self).__init__(*args, **kwargs)
|
||||
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.log.addHandler(self.handler)
|
||||
|
||||
|
@ -37,9 +39,9 @@ class LegendaryCore(LegendaryCoreReal):
|
|||
def unlock_installed(func):
|
||||
@functools.wraps(func)
|
||||
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():
|
||||
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)
|
||||
try:
|
||||
ret = func(self, *args, **kwargs)
|
||||
|
@ -50,6 +52,18 @@ class LegendaryCore(LegendaryCoreReal):
|
|||
return ret
|
||||
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
|
||||
# def get_installed_game(self, app_name, skip_sync=True) -> InstalledGame:
|
||||
# return super(LegendaryCore, self).get_installed_game(app_name, skip_sync)
|
||||
|
|
|
@ -18,6 +18,8 @@ def main() -> int:
|
|||
sys.stderr = open(os.devnull, 'w')
|
||||
|
||||
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
|
||||
multiprocessing.freeze_support()
|
||||
|
|
|
@ -97,15 +97,11 @@ class RareGameBase(QObject):
|
|||
|
||||
@property
|
||||
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
|
||||
def app_title(self) -> str:
|
||||
return self.igame.title if self.igame is not None else self.game.app_title
|
||||
|
||||
@property
|
||||
def title(self) -> str:
|
||||
return self.app_title
|
||||
return self.game.app_title
|
||||
|
||||
@property
|
||||
@abstractmethod
|
||||
|
@ -125,6 +121,10 @@ class RareGameBase(QObject):
|
|||
"""
|
||||
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
|
||||
def is_mac(self) -> bool:
|
||||
"""!
|
||||
|
@ -173,7 +173,7 @@ class RareGameBase(QObject):
|
|||
|
||||
@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
|
||||
def install_path(self) -> Optional[str]:
|
||||
|
@ -234,7 +234,7 @@ class RareGameSlim(RareGameBase):
|
|||
status, (dt_local, dt_remote) = self.save_game_state
|
||||
|
||||
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.core.upload_save(self.app_name, self.igame.save_path, dt_local)
|
||||
self.state = RareGameSlim.State.IDLE
|
||||
|
@ -246,7 +246,7 @@ class RareGameSlim(RareGameBase):
|
|||
logger.warning("Can't upload non existing save")
|
||||
return
|
||||
if self.state == RareGameSlim.State.SYNCING:
|
||||
logger.error(f"{self.title} is already syncing")
|
||||
logger.error(f"{self.app_title} is already syncing")
|
||||
return
|
||||
|
||||
if thread:
|
||||
|
@ -259,7 +259,7 @@ class RareGameSlim(RareGameBase):
|
|||
status, (dt_local, dt_remote) = self.save_game_state
|
||||
|
||||
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.core.download_saves(self.app_name, self.latest_save.file.manifest_name, self.save_path)
|
||||
self.state = RareGameSlim.State.IDLE
|
||||
|
@ -271,7 +271,7 @@ class RareGameSlim(RareGameBase):
|
|||
logger.error("Can't download non existing save")
|
||||
return
|
||||
if self.state == RareGameSlim.State.SYNCING:
|
||||
logger.error(f"{self.title} is already syncing")
|
||||
logger.error(f"{self.app_title} is already syncing")
|
||||
return
|
||||
|
||||
if thread:
|
||||
|
|
|
@ -166,7 +166,8 @@ class RareGame(RareGameSlim):
|
|||
|
||||
def update_game(self):
|
||||
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):
|
||||
|
@ -228,7 +229,7 @@ class RareGame(RareGameSlim):
|
|||
if self.igame is not None:
|
||||
return self.game.app_version(self.igame.platform)
|
||||
else:
|
||||
return self.game.app_version()
|
||||
return self.game.app_version(self.default_platform)
|
||||
|
||||
@property
|
||||
def has_update(self) -> bool:
|
||||
|
|
|
@ -70,15 +70,15 @@ class ImageSize:
|
|||
DisplayWide = Preset(1, 1, Orientation.Wide, base=ImageWide)
|
||||
"""! @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"""
|
||||
|
||||
Small = Preset(3, 1, base=Image)
|
||||
"""! @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"""
|
||||
|
||||
Smaller = Preset(4, 1, base=Image)
|
||||
|
|
|
@ -4,7 +4,7 @@ import time
|
|||
from argparse import Namespace
|
||||
from itertools import chain
|
||||
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 legendary.lfs.eos import EOSOverlayApp
|
||||
|
@ -25,6 +25,7 @@ from .workers import (
|
|||
)
|
||||
from .workers.uninstall import uninstall_game
|
||||
from .workers.worker import QueueWorkerInfo, QueueWorkerState
|
||||
from rare.utils import config_helper
|
||||
|
||||
logger = getLogger("RareCore")
|
||||
|
||||
|
@ -54,9 +55,10 @@ class RareCore(QObject):
|
|||
self.args(args)
|
||||
self.signals(init=True)
|
||||
self.core(init=True)
|
||||
config_helper.init_config_handler(self.__core)
|
||||
self.image_manager(init=True)
|
||||
|
||||
self.settings = QSettings()
|
||||
self.settings = QSettings(self)
|
||||
|
||||
self.queue_workers: List[QueueWorker] = []
|
||||
self.queue_threadpool = QThreadPool()
|
||||
|
@ -129,17 +131,44 @@ class RareCore(QObject):
|
|||
try:
|
||||
self.__core = LegendaryCore()
|
||||
except configparser.MissingSectionHeaderError as e:
|
||||
logger.warning(f"Config is corrupt: {e}")
|
||||
if config_path := os.environ.get("XDG_CONFIG_HOME"):
|
||||
path = os.path.join(config_path, "legendary")
|
||||
logger.warning("Config is corrupt: %s", e)
|
||||
if config_path := os.environ.get('LEGENDARY_CONFIG_PATH'):
|
||||
path = config_path
|
||||
elif config_path := os.environ.get('XDG_CONFIG_HOME'):
|
||||
path = os.path.join(config_path, 'legendary')
|
||||
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:
|
||||
config_file.write("[Legendary]")
|
||||
self.__core = LegendaryCore()
|
||||
|
||||
# Initialize sections if they don't exist
|
||||
for section in ["Legendary", "default", "default.env"]:
|
||||
if section not in self.__core.lgd.config.sections():
|
||||
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
|
||||
# programdata_path might be unset if logging in through the browser
|
||||
if self.__core.egl_sync_enabled:
|
||||
|
@ -148,6 +177,7 @@ class RareCore(QObject):
|
|||
else:
|
||||
if not os.path.exists(self.__core.egl.programdata_path):
|
||||
self.__core.lgd.config.remove_option("Legendary", "egl_sync")
|
||||
|
||||
self.__core.lgd.save_config()
|
||||
return self.__core
|
||||
|
||||
|
@ -176,7 +206,9 @@ class RareCore(QObject):
|
|||
del self.__args
|
||||
self.__args = None
|
||||
|
||||
del self.__eos_overlay
|
||||
# del self.__eos_overlay
|
||||
self.__eos_overlay = None
|
||||
|
||||
RareCore.__instance = None
|
||||
super(RareCore, self).deleteLater()
|
||||
|
||||
|
@ -357,7 +389,7 @@ class RareCore(QObject):
|
|||
yield game.game
|
||||
|
||||
@property
|
||||
def dlcs(self) -> Dict[str, Game]:
|
||||
def dlcs(self) -> Dict[str, set[RareGame]]:
|
||||
"""!
|
||||
RareGames that ARE DLCs themselves
|
||||
"""
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import platform
|
||||
import time
|
||||
from argparse import Namespace
|
||||
from enum import IntEnum
|
||||
from logging import getLogger
|
||||
|
||||
from PyQt5.QtCore import QObject, pyqtSignal
|
||||
from PyQt5.QtCore import QObject, pyqtSignal, QSettings
|
||||
from requests.exceptions import ConnectionError, HTTPError
|
||||
|
||||
from rare.lgndr.core import LegendaryCore
|
||||
|
@ -27,19 +28,54 @@ class FetchWorker(Worker):
|
|||
self.signals = FetchWorker.Signals()
|
||||
self.core = core
|
||||
self.args = args
|
||||
self.settings = QSettings()
|
||||
|
||||
def run_real(self):
|
||||
# Fetch regular EGL games with assets
|
||||
self.signals.progress.emit(0, self.signals.tr("Updating game metadata"))
|
||||
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(
|
||||
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"Request games: {time.time() - start_time} seconds")
|
||||
|
||||
# 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()
|
||||
try:
|
||||
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:
|
||||
logger.debug("Found Unix install directory %s", install_dir)
|
||||
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:
|
||||
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 os.path.isdir(install_dir):
|
||||
install_size = path_size(install_dir)
|
||||
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:
|
||||
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:
|
||||
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)
|
||||
|
|
|
@ -14,7 +14,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets
|
|||
class Ui_ImportGroup(object):
|
||||
def setupUi(self, ImportGroup):
|
||||
ImportGroup.setObjectName("ImportGroup")
|
||||
ImportGroup.resize(506, 184)
|
||||
ImportGroup.resize(651, 218)
|
||||
ImportGroup.setWindowTitle("ImportGroup")
|
||||
ImportGroup.setWindowFilePath("")
|
||||
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_folder_label = QtWidgets.QLabel(ImportGroup)
|
||||
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)
|
||||
font = QtGui.QFont()
|
||||
font.setItalic(True)
|
||||
self.import_folder_check.setFont(font)
|
||||
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.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)
|
||||
font = QtGui.QFont()
|
||||
font.setItalic(True)
|
||||
self.import_dlcs_check.setFont(font)
|
||||
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.setText("Error")
|
||||
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.setObjectName("button_info_layout")
|
||||
self.import_button = QtWidgets.QPushButton(ImportGroup)
|
||||
|
@ -58,16 +67,27 @@ class Ui_ImportGroup(object):
|
|||
self.import_button.setSizePolicy(sizePolicy)
|
||||
self.import_button.setObjectName("import_button")
|
||||
self.button_info_layout.addWidget(self.import_button)
|
||||
self.import_layout.setLayout(5, QtWidgets.QFormLayout.FieldRole, self.button_info_layout)
|
||||
self.import_force_label = QtWidgets.QLabel(ImportGroup)
|
||||
self.import_force_label.setObjectName("import_force_label")
|
||||
self.import_layout.setWidget(4, QtWidgets.QFormLayout.LabelRole, self.import_force_label)
|
||||
self.import_force_check = QtWidgets.QCheckBox(ImportGroup)
|
||||
self.import_layout.setLayout(6, QtWidgets.QFormLayout.FieldRole, self.button_info_layout)
|
||||
self.platform_label = QtWidgets.QLabel(ImportGroup)
|
||||
self.platform_label.setObjectName("platform_label")
|
||||
self.import_layout.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.platform_label)
|
||||
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.setItalic(True)
|
||||
self.import_force_check.setFont(font)
|
||||
self.import_force_check.setObjectName("import_force_check")
|
||||
self.import_layout.setWidget(4, QtWidgets.QFormLayout.FieldRole, self.import_force_check)
|
||||
self.platform_tooltip.setFont(font)
|
||||
self.platform_tooltip.setObjectName("platform_tooltip")
|
||||
self.platform_layout.addWidget(self.platform_tooltip)
|
||||
self.import_layout.setLayout(2, QtWidgets.QFormLayout.FieldRole, self.platform_layout)
|
||||
|
||||
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_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_button.setText(_translate("ImportGroup", "Import Game"))
|
||||
self.import_force_label.setText(_translate("ImportGroup", "Force import"))
|
||||
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__":
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>506</width>
|
||||
<height>184</height>
|
||||
<width>651</width>
|
||||
<height>218</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
|
@ -37,14 +37,14 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="import_folder_label">
|
||||
<property name="text">
|
||||
<string>Import all folders</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<item row="3" column="1">
|
||||
<widget class="QCheckBox" name="import_folder_check">
|
||||
<property name="font">
|
||||
<font>
|
||||
|
@ -56,14 +56,14 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="import_dlcs_label">
|
||||
<property name="text">
|
||||
<string>Import DLCs</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<item row="4" column="1">
|
||||
<widget class="QCheckBox" name="import_dlcs_check">
|
||||
<property name="font">
|
||||
<font>
|
||||
|
@ -76,13 +76,32 @@
|
|||
</widget>
|
||||
</item>
|
||||
<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">
|
||||
<property name="text">
|
||||
<string notr="true">Error</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<item row="6" column="1">
|
||||
<layout class="QHBoxLayout" name="button_info_layout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="import_button">
|
||||
|
@ -99,24 +118,38 @@
|
|||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="import_force_label">
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="platform_label">
|
||||
<property name="text">
|
||||
<string>Force import</string>
|
||||
<string>Platform</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" 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 row="2" column="1">
|
||||
<layout class="QHBoxLayout" name="platform_layout">
|
||||
<item>
|
||||
<widget class="QComboBox" name="platform_combo">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</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>
|
||||
</layout>
|
||||
</widget>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
# 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
|
||||
# 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):
|
||||
def setupUi(self, LegendarySettings):
|
||||
LegendarySettings.setObjectName("LegendarySettings")
|
||||
LegendarySettings.resize(595, 334)
|
||||
LegendarySettings.resize(681, 456)
|
||||
LegendarySettings.setWindowTitle("LegendarySettings")
|
||||
self.legendary_layout = QtWidgets.QHBoxLayout(LegendarySettings)
|
||||
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.setObjectName("clean_button")
|
||||
self.cleanup_layout.addWidget(self.clean_button)
|
||||
self.right_layout.addWidget(self.cleanup_group, 0, QtCore.Qt.AlignTop)
|
||||
self.meta_group = QtWidgets.QGroupBox(LegendarySettings)
|
||||
self.meta_group.setObjectName("meta_group")
|
||||
self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.meta_group)
|
||||
self.right_layout.addWidget(self.cleanup_group)
|
||||
self.metadata_group = QtWidgets.QGroupBox(LegendarySettings)
|
||||
self.metadata_group.setObjectName("metadata_group")
|
||||
self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.metadata_group)
|
||||
self.verticalLayout_2.setObjectName("verticalLayout_2")
|
||||
self.win32_cb = QtWidgets.QCheckBox(self.meta_group)
|
||||
self.win32_cb.setObjectName("win32_cb")
|
||||
self.verticalLayout_2.addWidget(self.win32_cb)
|
||||
self.mac_cb = QtWidgets.QCheckBox(self.meta_group)
|
||||
self.mac_cb.setObjectName("mac_cb")
|
||||
self.verticalLayout_2.addWidget(self.mac_cb)
|
||||
self.refresh_game_meta_btn = QtWidgets.QPushButton(self.meta_group)
|
||||
self.refresh_game_meta_btn.setObjectName("refresh_game_meta_btn")
|
||||
self.verticalLayout_2.addWidget(self.refresh_game_meta_btn)
|
||||
self.right_layout.addWidget(self.meta_group)
|
||||
self.fetch_win32_check = QtWidgets.QCheckBox(self.metadata_group)
|
||||
self.fetch_win32_check.setObjectName("fetch_win32_check")
|
||||
self.verticalLayout_2.addWidget(self.fetch_win32_check)
|
||||
self.fetch_macos_check = QtWidgets.QCheckBox(self.metadata_group)
|
||||
self.fetch_macos_check.setObjectName("fetch_macos_check")
|
||||
self.verticalLayout_2.addWidget(self.fetch_macos_check)
|
||||
self.fetch_unreal_check = QtWidgets.QCheckBox(self.metadata_group)
|
||||
self.fetch_unreal_check.setObjectName("fetch_unreal_check")
|
||||
self.verticalLayout_2.addWidget(self.fetch_unreal_check)
|
||||
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)
|
||||
self.right_layout.addItem(spacerItem1)
|
||||
self.legendary_layout.addLayout(self.right_layout)
|
||||
|
@ -148,11 +157,11 @@ class Ui_LegendarySettings(object):
|
|||
|
||||
def retranslateUi(self, LegendarySettings):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
self.install_dir_group.setTitle(_translate("LegendarySettings", "Default Installation Directory"))
|
||||
self.download_group.setTitle(_translate("LegendarySettings", "Download Settings"))
|
||||
self.max_workers_label.setText(_translate("LegendarySettings", "Max Workers"))
|
||||
self.install_dir_group.setTitle(_translate("LegendarySettings", "Default installation folder"))
|
||||
self.download_group.setTitle(_translate("LegendarySettings", "Download settings"))
|
||||
self.max_workers_label.setText(_translate("LegendarySettings", "Max sorkers"))
|
||||
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_info_label.setText(_translate("LegendarySettings", "Less is slower (0: Default)"))
|
||||
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.clean_keep_manifests_button.setText(_translate("LegendarySettings", "Clean, but keep manifests"))
|
||||
self.clean_button.setText(_translate("LegendarySettings", "Remove everything"))
|
||||
self.meta_group.setTitle(_translate("LegendarySettings", "Game metadata"))
|
||||
self.win32_cb.setText(_translate("LegendarySettings", "Load 32bit data"))
|
||||
self.mac_cb.setText(_translate("LegendarySettings", "Load MacOS data"))
|
||||
self.refresh_game_meta_btn.setText(_translate("LegendarySettings", "Refresh game meta"))
|
||||
self.metadata_group.setTitle(_translate("LegendarySettings", "Platforms"))
|
||||
self.fetch_win32_check.setText(_translate("LegendarySettings", "Include Win32 games"))
|
||||
self.fetch_macos_check.setText(_translate("LegendarySettings", "Include macOS games"))
|
||||
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__":
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>595</width>
|
||||
<height>334</height>
|
||||
<width>681</width>
|
||||
<height>456</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
|
@ -19,7 +19,7 @@
|
|||
<item alignment="Qt::AlignTop">
|
||||
<widget class="QGroupBox" name="install_dir_group">
|
||||
<property name="title">
|
||||
<string>Default Installation Directory</string>
|
||||
<string>Default installation folder</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
|
@ -30,7 +30,7 @@
|
|||
<item alignment="Qt::AlignTop">
|
||||
<widget class="QGroupBox" name="download_group">
|
||||
<property name="title">
|
||||
<string>Download Settings</string>
|
||||
<string>Download settings</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
|
@ -48,7 +48,7 @@
|
|||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Max Workers</string>
|
||||
<string>Max sorkers</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -90,7 +90,7 @@
|
|||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="max_memory_label">
|
||||
<property name="text">
|
||||
<string>Max Shared Memory</string>
|
||||
<string>Max shared memory</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -200,7 +200,7 @@
|
|||
<layout class="QVBoxLayout" name="locale_layout"/>
|
||||
</widget>
|
||||
</item>
|
||||
<item alignment="Qt::AlignTop">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="cleanup_group">
|
||||
<property name="title">
|
||||
<string>Cleanup</string>
|
||||
|
@ -227,29 +227,48 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="meta_group">
|
||||
<widget class="QGroupBox" name="metadata_group">
|
||||
<property name="title">
|
||||
<string>Game metadata</string>
|
||||
<string>Platforms</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="win32_cb">
|
||||
<widget class="QCheckBox" name="fetch_win32_check">
|
||||
<property name="text">
|
||||
<string>Load 32bit data</string>
|
||||
<string>Include Win32 games</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="mac_cb">
|
||||
<widget class="QCheckBox" name="fetch_macos_check">
|
||||
<property name="text">
|
||||
<string>Load MacOS data</string>
|
||||
<string>Include macOS games</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="refresh_game_meta_btn">
|
||||
<widget class="QCheckBox" name="fetch_unreal_check">
|
||||
<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>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
# 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
|
||||
# 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):
|
||||
def setupUi(self, RareSettings):
|
||||
RareSettings.setObjectName("RareSettings")
|
||||
RareSettings.resize(517, 434)
|
||||
RareSettings.resize(623, 428)
|
||||
RareSettings.setWindowTitle("RareSettings")
|
||||
self.rare_layout = QtWidgets.QHBoxLayout(RareSettings)
|
||||
self.rare_layout.setObjectName("rare_layout")
|
||||
|
@ -148,25 +148,25 @@ class Ui_RareSettings(object):
|
|||
_translate = QtCore.QCoreApplication.translate
|
||||
self.interface_group.setTitle(_translate("RareSettings", "Interface"))
|
||||
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.style_label.setText(_translate("RareSettings", "Style Sheet"))
|
||||
self.style_label.setText(_translate("RareSettings", "Style sheet"))
|
||||
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.save_size.setText(_translate("RareSettings", "Restore window size on application startup"))
|
||||
self.notification.setText(_translate("RareSettings", "Show notification on download completion"))
|
||||
self.log_games.setText(_translate("RareSettings", "Show console for game debug"))
|
||||
self.sys_tray.setText(_translate("RareSettings", "Exit to System tray"))
|
||||
self.auto_update.setText(_translate("RareSettings", "Update games on application startup"))
|
||||
self.confirm_start.setText(_translate("RareSettings", "Confirm game launch"))
|
||||
self.auto_sync_cloud.setText(_translate("RareSettings", "Automatically sync with cloud"))
|
||||
self.notification.setText(_translate("RareSettings", "Show notifications when downloads complete"))
|
||||
self.log_games.setText(_translate("RareSettings", "Show console windows when launching games"))
|
||||
self.sys_tray.setText(_translate("RareSettings", "Exit to system tray"))
|
||||
self.auto_update.setText(_translate("RareSettings", "Queue game updates on application startup"))
|
||||
self.confirm_start.setText(_translate("RareSettings", "Confirm before launching games"))
|
||||
self.auto_sync_cloud.setText(_translate("RareSettings", "Automatically upload/download cloud saves"))
|
||||
self.log_dir_group.setTitle(_translate("RareSettings", "Logs"))
|
||||
self.log_dir_open_button.setText(_translate("RareSettings", "Open Log directory"))
|
||||
self.log_dir_clean_button.setText(_translate("RareSettings", "Clean Log directory"))
|
||||
self.log_dir_open_button.setText(_translate("RareSettings", "Open log folder"))
|
||||
self.log_dir_clean_button.setText(_translate("RareSettings", "Clean log folder"))
|
||||
self.groupBox.setTitle(_translate("RareSettings", "Shortcuts"))
|
||||
self.desktop_link_btn.setText(_translate("RareSettings", "Create Desktop link"))
|
||||
self.startmenu_link_btn.setText(_translate("RareSettings", "Create start menu link"))
|
||||
self.desktop_link_btn.setText(_translate("RareSettings", "Create on desktop"))
|
||||
self.startmenu_link_btn.setText(_translate("RareSettings", "Create in menu"))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>517</width>
|
||||
<height>434</height>
|
||||
<width>623</width>
|
||||
<height>428</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
|
@ -51,7 +51,7 @@
|
|||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="color_label">
|
||||
<property name="text">
|
||||
<string>Color Scheme</string>
|
||||
<string>Color scheme</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -73,7 +73,7 @@
|
|||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="style_label">
|
||||
<property name="text">
|
||||
<string>Style Sheet</string>
|
||||
<string>Style sheet</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -100,7 +100,7 @@
|
|||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Restart Rare to apply.</string>
|
||||
<string>Restart Rare to apply changes.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
|
@ -126,42 +126,42 @@
|
|||
<item row="4" column="0">
|
||||
<widget class="QCheckBox" name="notification">
|
||||
<property name="text">
|
||||
<string>Show notification on download completion</string>
|
||||
<string>Show notifications when downloads complete</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QCheckBox" name="log_games">
|
||||
<property name="text">
|
||||
<string>Show console for game debug</string>
|
||||
<string>Show console windows when launching games</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="sys_tray">
|
||||
<property name="text">
|
||||
<string>Exit to System tray</string>
|
||||
<string>Exit to system tray</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="auto_update">
|
||||
<property name="text">
|
||||
<string>Update games on application startup</string>
|
||||
<string>Queue game updates on application startup</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="confirm_start">
|
||||
<property name="text">
|
||||
<string>Confirm game launch</string>
|
||||
<string>Confirm before launching games</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="auto_sync_cloud">
|
||||
<property name="text">
|
||||
<string>Automatically sync with cloud</string>
|
||||
<string>Automatically upload/download cloud saves</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -207,14 +207,14 @@
|
|||
<item>
|
||||
<widget class="QPushButton" name="log_dir_open_button">
|
||||
<property name="text">
|
||||
<string>Open Log directory</string>
|
||||
<string>Open log folder</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="log_dir_clean_button">
|
||||
<property name="text">
|
||||
<string>Clean Log directory</string>
|
||||
<string>Clean log folder</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -246,14 +246,14 @@
|
|||
<item>
|
||||
<widget class="QPushButton" name="desktop_link_btn">
|
||||
<property name="text">
|
||||
<string>Create Desktop link</string>
|
||||
<string>Create on desktop</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="startmenu_link_btn">
|
||||
<property name="text">
|
||||
<string>Create start menu link</string>
|
||||
<string>Create in menu</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
|
@ -1,33 +1,55 @@
|
|||
from typing import Optional
|
||||
from typing import Optional, List, overload
|
||||
|
||||
from PyQt5.QtCore import (
|
||||
Qt,
|
||||
QRect,
|
||||
QSize,
|
||||
QPoint,
|
||||
)
|
||||
from PyQt5.QtWidgets import (
|
||||
QLayout,
|
||||
QStyle,
|
||||
QSizePolicy,
|
||||
QLayoutItem,
|
||||
)
|
||||
from PyQt5.QtCore import Qt, QRect, QSize, QPoint
|
||||
from PyQt5.QtWidgets import QLayout, QStyle, QSizePolicy, QLayoutItem, QWidget
|
||||
|
||||
|
||||
class FlowLayout(QLayout):
|
||||
def __init__(self, parent=None, margin=-1, hspacing=-1, vspacing=-1):
|
||||
def __init__(self, parent=None):
|
||||
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._hspacing = -1
|
||||
self._vspacing = -1
|
||||
self._items: List[QLayoutItem] = []
|
||||
|
||||
def __del__(self):
|
||||
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:
|
||||
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):
|
||||
if self._hspacing >= 0:
|
||||
|
@ -35,6 +57,10 @@ class FlowLayout(QLayout):
|
|||
else:
|
||||
return self.smartSpacing(QStyle.PM_LayoutHorizontalSpacing)
|
||||
|
||||
def setVerticalSpacing(self, a0: int) -> None:
|
||||
self._vspacing = a0
|
||||
self.invalidate()
|
||||
|
||||
def verticalSpacing(self):
|
||||
if self._vspacing >= 0:
|
||||
return self._vspacing
|
||||
|
@ -51,11 +77,14 @@ class FlowLayout(QLayout):
|
|||
|
||||
def takeAt(self, index: int) -> Optional[QLayoutItem]:
|
||||
if 0 <= index < len(self._items):
|
||||
return self._items.pop(index)
|
||||
item = self._items.pop(index)
|
||||
self.invalidate()
|
||||
return item
|
||||
return None
|
||||
|
||||
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:
|
||||
return True
|
||||
|
@ -93,8 +122,6 @@ class FlowLayout(QLayout):
|
|||
if item.isEmpty():
|
||||
continue
|
||||
widget = item.widget()
|
||||
if not widget.isVisible():
|
||||
continue
|
||||
hspace = self.horizontalSpacing()
|
||||
if hspace == -1:
|
||||
hspace = widget.style().layoutSpacing(
|
||||
|
|
|
@ -4,7 +4,6 @@ from logging import getLogger
|
|||
from typing import Callable, Tuple, Optional, Dict, List
|
||||
|
||||
from PyQt5.QtCore import (
|
||||
Qt,
|
||||
QSize,
|
||||
pyqtSignal,
|
||||
QFileInfo,
|
||||
|
@ -135,7 +134,8 @@ class IndicatorLineEdit(QWidget):
|
|||
# Add line_edit
|
||||
self.line_edit = QLineEdit(self)
|
||||
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)
|
||||
# Add completer
|
||||
self.setCompleter(completer)
|
||||
|
|
|
@ -1,23 +1,18 @@
|
|||
from typing import Callable
|
||||
|
||||
from PyQt5.QtCore import (
|
||||
Qt,
|
||||
QRect,
|
||||
QPoint,
|
||||
)
|
||||
from PyQt5.QtWidgets import (
|
||||
QSizePolicy,
|
||||
)
|
||||
from PyQt5.QtCore import Qt, QRect, QPoint
|
||||
from PyQt5.QtWidgets import QSizePolicy
|
||||
|
||||
from .flow_layout import FlowLayout
|
||||
|
||||
|
||||
class LibraryLayout(FlowLayout):
|
||||
def __init__(self, parent=None, margin=6, spacing=11):
|
||||
super(LibraryLayout, self).__init__(parent=parent, margin=margin, hspacing=spacing, vspacing=spacing)
|
||||
def __init__(self, parent=None):
|
||||
super(LibraryLayout, self).__init__(parent)
|
||||
|
||||
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:
|
||||
super(FlowLayout, self).setGeometry(a0)
|
||||
|
@ -127,4 +122,4 @@ class LibraryLayout(FlowLayout):
|
|||
|
||||
def sort(self, key: Callable, reverse=False) -> None:
|
||||
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