Merge pull request #364 from loathingKernel/next
Enable launchable addons such as Fortnite Experiences as games in the library.
This commit is contained in:
commit
4e0f3ab59c
|
@ -31,7 +31,7 @@ class RareException(RareAppException):
|
|||
except Exception as e:
|
||||
self.logger.fatal(str(e))
|
||||
QMessageBox.warning(None, "Error", self.tr("Failed to login"))
|
||||
QApplication.exit(1)
|
||||
QApplication.quit()
|
||||
return False
|
||||
|
||||
|
||||
|
@ -51,7 +51,7 @@ class Rare(RareApp):
|
|||
# set Application name for settings
|
||||
self.main_window: Optional[MainWindow] = None
|
||||
self.launch_dialog: Optional[LaunchDialog] = None
|
||||
self.timer: Optional[QTimer] = None
|
||||
self.relogin_timer: Optional[QTimer] = None
|
||||
|
||||
# This launches the application after it has been instantiated.
|
||||
# The timer's signal will be serviced once we call `exec()` on the application
|
||||
|
@ -61,15 +61,15 @@ class Rare(RareApp):
|
|||
dt_exp = datetime.fromisoformat(self.core.lgd.userdata['expires_at'][:-1]).replace(tzinfo=timezone.utc)
|
||||
dt_now = datetime.utcnow().replace(tzinfo=timezone.utc)
|
||||
td = abs(dt_exp - dt_now)
|
||||
self.timer.start(int(td.total_seconds() - 60) * 1000)
|
||||
self.relogin_timer.start(int(td.total_seconds() - 60) * 1000)
|
||||
self.logger.info(f"Renewed session expires at {self.core.lgd.userdata['expires_at']}")
|
||||
|
||||
def re_login(self):
|
||||
def relogin(self):
|
||||
self.logger.info("Session expires shortly. Renew session")
|
||||
try:
|
||||
self.core.login()
|
||||
self.core.login(force_refresh=True)
|
||||
except requests.exceptions.ConnectionError:
|
||||
self.timer.start(3000) # try again if no connection
|
||||
self.relogin_timer.start(3000) # try again if no connection
|
||||
return
|
||||
self.poke_timer()
|
||||
|
||||
|
@ -85,8 +85,9 @@ class Rare(RareApp):
|
|||
|
||||
@pyqtSlot()
|
||||
def __on_start_app(self):
|
||||
self.timer = QTimer()
|
||||
self.timer.timeout.connect(self.re_login)
|
||||
self.relogin_timer = QTimer(self)
|
||||
self.relogin_timer.setTimerType(Qt.VeryCoarseTimer)
|
||||
self.relogin_timer.timeout.connect(self.relogin)
|
||||
self.poke_timer()
|
||||
|
||||
self.main_window = MainWindow()
|
||||
|
@ -105,10 +106,10 @@ class Rare(RareApp):
|
|||
def __on_exit_app(self, exit_code=0):
|
||||
threadpool = QThreadPool.globalInstance()
|
||||
threadpool.waitForDone()
|
||||
if self.timer is not None:
|
||||
self.timer.stop()
|
||||
self.timer.deleteLater()
|
||||
self.timer = None
|
||||
if self.relogin_timer is not None:
|
||||
self.relogin_timer.stop()
|
||||
self.relogin_timer.deleteLater()
|
||||
self.relogin_timer = None
|
||||
self.rcore.deleteLater()
|
||||
del self.rcore
|
||||
self.processEvents()
|
||||
|
|
|
@ -1,94 +0,0 @@
|
|||
import datetime
|
||||
import sys
|
||||
from logging import getLogger
|
||||
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5.QtWidgets import QDialog, QSizePolicy, QLayout, QApplication, QWidget
|
||||
from legendary.core import LegendaryCore
|
||||
from legendary.models.game import InstalledGame
|
||||
|
||||
from rare.ui.components.dialogs.sync_save_dialog import Ui_SyncSaveDialog
|
||||
from rare.ui.components.tabs.games.game_info.sync_widget import Ui_SyncWidget
|
||||
from rare.utils.misc import icon
|
||||
|
||||
logger = getLogger("Cloud Saves")
|
||||
|
||||
|
||||
class CloudSaveDialog(QDialog, Ui_SyncSaveDialog):
|
||||
DOWNLOAD = 2
|
||||
UPLOAD = 1
|
||||
CANCEL = 0
|
||||
SKIP = 3
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
igame: InstalledGame,
|
||||
dt_local: datetime.datetime,
|
||||
dt_remote: datetime.datetime,
|
||||
):
|
||||
super(CloudSaveDialog, self).__init__()
|
||||
self.setupUi(self)
|
||||
|
||||
self.sync_widget = QWidget()
|
||||
self.sync_ui = Ui_SyncWidget()
|
||||
self.sync_ui.setupUi(self.sync_widget)
|
||||
|
||||
self.sync_widget_layout.addWidget(self.sync_widget)
|
||||
|
||||
self.setAttribute(Qt.WA_DeleteOnClose, True)
|
||||
self.setWindowFlags(Qt.Dialog | Qt.CustomizeWindowHint | Qt.WindowTitleHint)
|
||||
|
||||
self.status = self.CANCEL
|
||||
|
||||
self.title_label.setText(f"{self.title_label.text()} <b>{igame.title}</b>")
|
||||
|
||||
newer = self.tr("Newer")
|
||||
if dt_remote and dt_local:
|
||||
self.sync_ui.age_label_local.setText(
|
||||
f"<b>{newer}</b>" if dt_remote < dt_local else " "
|
||||
)
|
||||
self.sync_ui.age_label_remote.setText(
|
||||
f"<b>{newer}</b>" if dt_remote > dt_local else " "
|
||||
)
|
||||
# Set status, if one of them is None
|
||||
elif dt_remote and not dt_local:
|
||||
self.status = self.DOWNLOAD
|
||||
elif not dt_remote and dt_local:
|
||||
self.status = self.UPLOAD
|
||||
else:
|
||||
self.status = self.SKIP
|
||||
|
||||
self.sync_ui.date_info_local.setText(dt_local.strftime("%A, %d. %B %Y %X") if dt_local else "None")
|
||||
self.sync_ui.date_info_remote.setText(dt_remote.strftime("%A, %d. %B %Y %X") if dt_remote else "None")
|
||||
|
||||
self.sync_ui.icon_local.setPixmap(icon("mdi.harddisk", "fa.desktop").pixmap(128, 128))
|
||||
self.sync_ui.icon_remote.setPixmap(icon("mdi.cloud-outline", "ei.cloud").pixmap(128, 128))
|
||||
|
||||
self.sync_ui.upload_button.clicked.connect(lambda: self.btn_clicked(self.UPLOAD))
|
||||
self.sync_ui.download_button.clicked.connect(lambda: self.btn_clicked(self.DOWNLOAD))
|
||||
self.cancel_button.clicked.connect(self.close)
|
||||
|
||||
self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
|
||||
self.layout().setSizeConstraint(QLayout.SetFixedSize)
|
||||
|
||||
def get_action(self):
|
||||
if self.status == self.SKIP:
|
||||
return self.SKIP
|
||||
self.exec_()
|
||||
return self.status
|
||||
|
||||
def btn_clicked(self, status):
|
||||
self.status = status
|
||||
self.close()
|
||||
|
||||
|
||||
def test_dialog():
|
||||
app = QApplication(sys.argv)
|
||||
core = LegendaryCore()
|
||||
dlg = CloudSaveDialog(core.get_installed_list()[0], datetime.datetime.now(),
|
||||
datetime.datetime.strptime("2021,1", "%Y,%M"))
|
||||
print(dlg.get_action())
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_dialog()
|
|
@ -3,49 +3,63 @@ import platform as pf
|
|||
import shutil
|
||||
from typing import Tuple, List, Union, Optional
|
||||
|
||||
from PyQt5.QtCore import Qt, QThreadPool, QSettings, QCoreApplication
|
||||
from PyQt5.QtCore import QThreadPool, QSettings
|
||||
from PyQt5.QtCore import pyqtSignal, pyqtSlot
|
||||
from PyQt5.QtGui import QCloseEvent, QKeyEvent, QShowEvent
|
||||
from PyQt5.QtWidgets import QDialog, QFileDialog, QCheckBox, QLayout, QWidget, QVBoxLayout, QFormLayout
|
||||
from PyQt5.QtGui import QShowEvent
|
||||
from PyQt5.QtWidgets import QFileDialog, QCheckBox, QWidget, QVBoxLayout, QFormLayout
|
||||
from legendary.utils.selective_dl import get_sdl_appname
|
||||
|
||||
from rare.models.game import RareGame
|
||||
from rare.models.install import InstallDownloadModel, InstallQueueItemModel, InstallOptionsModel
|
||||
from rare.shared import LegendaryCoreSingleton, ArgumentsSingleton
|
||||
from rare.shared.workers.install_info import InstallInfoWorker
|
||||
from rare.ui.components.dialogs.install_dialog import Ui_InstallDialog
|
||||
from rare.ui.components.dialogs.install_dialog_advanced import Ui_InstallDialogAdvanced
|
||||
from rare.utils import config_helper
|
||||
from rare.utils.misc import format_size
|
||||
from rare.utils.misc import format_size, icon
|
||||
from rare.widgets.dialogs import ActionDialog, dialog_title_game
|
||||
from rare.widgets.collapsible_widget import CollapsibleFrame
|
||||
from rare.widgets.indicator_edit import PathEdit, IndicatorReasonsCommon
|
||||
|
||||
|
||||
class InstallDialogAdvanced(CollapsibleFrame):
|
||||
def __init__(self, parent=None):
|
||||
widget = QWidget()
|
||||
widget = QWidget(parent)
|
||||
title = widget.tr("Advanced options")
|
||||
self.ui = Ui_InstallDialogAdvanced()
|
||||
self.ui.setupUi(widget)
|
||||
super(InstallDialogAdvanced, self).__init__(widget=widget, title=title, parent=parent)
|
||||
|
||||
|
||||
class InstallDialog(QDialog):
|
||||
class InstallDialog(ActionDialog):
|
||||
result_ready = pyqtSignal(InstallQueueItemModel)
|
||||
|
||||
def __init__(self, rgame: RareGame, options: InstallOptionsModel, parent=None):
|
||||
super(InstallDialog, self).__init__(parent=parent)
|
||||
self.ui = Ui_InstallDialog()
|
||||
self.ui.setupUi(self)
|
||||
self.setAttribute(Qt.WA_DeleteOnClose, True)
|
||||
self.setWindowFlags(Qt.Dialog | Qt.CustomizeWindowHint | Qt.WindowTitleHint)
|
||||
# lk: set object names for CSS properties
|
||||
self.ui.install_button.setObjectName("InstallButton")
|
||||
|
||||
self.core = LegendaryCoreSingleton()
|
||||
header = self.tr("Install")
|
||||
bicon = icon("ri.install-line")
|
||||
if options.repair_mode:
|
||||
header = self.tr("Repair")
|
||||
bicon = icon("fa.wrench")
|
||||
if options.repair_and_update:
|
||||
header = self.tr("Repair and update")
|
||||
elif options.update:
|
||||
header = self.tr("Update")
|
||||
elif options.reset_sdl:
|
||||
header = self.tr("Modify")
|
||||
bicon = icon("fa.gear")
|
||||
self.setWindowTitle(dialog_title_game(header, rgame.app_title))
|
||||
|
||||
install_widget = QWidget(self)
|
||||
self.ui = Ui_InstallDialog()
|
||||
self.ui.setupUi(install_widget)
|
||||
|
||||
self.ui.title_label.setText(f"<h4>{dialog_title_game(header, rgame.app_title)}</h4>")
|
||||
|
||||
self.core = rgame.core
|
||||
self.rgame = rgame
|
||||
self.options = options
|
||||
self.__options: InstallOptionsModel = options
|
||||
self.__download: Optional[InstallDownloadModel] = None
|
||||
self.__queue_item: Optional[InstallQueueItemModel] = None
|
||||
|
||||
self.advanced = InstallDialogAdvanced(parent=self)
|
||||
self.ui.advanced_layout.addWidget(self.advanced)
|
||||
|
@ -54,25 +68,10 @@ class InstallDialog(QDialog):
|
|||
self.ui.selectable_layout.addWidget(self.selectable)
|
||||
|
||||
self.options_changed = False
|
||||
self.worker_running = False
|
||||
self.reject_close = True
|
||||
|
||||
self.threadpool = QThreadPool(self)
|
||||
self.threadpool.setMaxThreadCount(1)
|
||||
|
||||
if options.repair_mode:
|
||||
header = self.tr("Repair")
|
||||
if options.repair_and_update:
|
||||
header = self.tr("Repair and update")
|
||||
elif options.update:
|
||||
header = self.tr("Update")
|
||||
elif options.reset_sdl:
|
||||
header = self.tr("Modify")
|
||||
else:
|
||||
header = self.tr("Install")
|
||||
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 options.base_path:
|
||||
base_path = options.base_path
|
||||
elif rgame.is_installed:
|
||||
|
@ -87,8 +86,8 @@ class InstallDialog(QDialog):
|
|||
save_func=self.save_install_edit,
|
||||
parent=self,
|
||||
)
|
||||
self.ui.install_dialog_layout.setWidget(
|
||||
self.ui.install_dialog_layout.getWidgetPosition(self.ui.install_dir_label)[0],
|
||||
self.ui.main_layout.setWidget(
|
||||
self.ui.main_layout.getWidgetPosition(self.ui.install_dir_label)[0],
|
||||
QFormLayout.FieldRole, self.install_dir_edit
|
||||
)
|
||||
|
||||
|
@ -111,6 +110,11 @@ class InstallDialog(QDialog):
|
|||
self.ui.platform_label.setDisabled(rgame.is_installed)
|
||||
self.ui.platform_combo.setDisabled(rgame.is_installed)
|
||||
|
||||
# if we are repairing, disable the SDL selection and open the dialog frame to be visible
|
||||
self.selectable.setDisabled(options.repair_mode and not options.repair_and_update)
|
||||
if options.repair_mode and not options.repair_and_update:
|
||||
self.selectable.click()
|
||||
|
||||
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)
|
||||
|
||||
|
@ -134,9 +138,9 @@ class InstallDialog(QDialog):
|
|||
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.accept_button.setEnabled(False)
|
||||
|
||||
if self.options.overlay:
|
||||
if self.__options.overlay:
|
||||
self.ui.platform_label.setEnabled(False)
|
||||
self.ui.platform_combo.setEnabled(False)
|
||||
self.advanced.ui.ignore_space_label.setEnabled(False)
|
||||
|
@ -161,13 +165,17 @@ class InstallDialog(QDialog):
|
|||
|
||||
self.non_reload_option_changed("shortcut")
|
||||
|
||||
self.ui.cancel_button.clicked.connect(self.__on_cancel)
|
||||
self.ui.verify_button.clicked.connect(self.__on_verify)
|
||||
self.ui.install_button.clicked.connect(self.__on_install)
|
||||
self.advanced.ui.install_prereqs_check.setChecked(self.__options.install_prereqs)
|
||||
|
||||
self.advanced.ui.install_prereqs_check.setChecked(self.options.install_prereqs)
|
||||
# lk: set object names for CSS properties
|
||||
self.accept_button.setText(header)
|
||||
self.accept_button.setIcon(bicon)
|
||||
self.accept_button.setObjectName("InstallButton")
|
||||
|
||||
self.ui.install_dialog_layout.setSizeConstraint(QLayout.SetFixedSize)
|
||||
self.action_button.setText(self.tr("Verify"))
|
||||
self.action_button.setIcon(icon("fa.check"))
|
||||
|
||||
self.setCentralWidget(install_widget)
|
||||
|
||||
def showEvent(self, a0: QShowEvent) -> None:
|
||||
if a0.spontaneous():
|
||||
|
@ -176,13 +184,11 @@ class InstallDialog(QDialog):
|
|||
super().showEvent(a0)
|
||||
|
||||
def execute(self):
|
||||
if self.options.silent:
|
||||
self.reject_close = False
|
||||
if self.__options.silent:
|
||||
self.get_download_info()
|
||||
else:
|
||||
self.setModal(True)
|
||||
self.__on_verify()
|
||||
self.show()
|
||||
self.action_handler()
|
||||
self.open()
|
||||
|
||||
@pyqtSlot(int)
|
||||
def reset_install_dir(self, index: int):
|
||||
|
@ -210,7 +216,7 @@ class InstallDialog(QDialog):
|
|||
layout = QVBoxLayout(widget)
|
||||
layout.setSpacing(0)
|
||||
for tag, info in sdl_data.items():
|
||||
cb = TagCheckBox(info["name"], info["description"], info["tags"])
|
||||
cb = TagCheckBox(info["name"].strip(), info["description"].strip(), info["tags"])
|
||||
if tag == "__required":
|
||||
cb.setChecked(True)
|
||||
cb.setDisabled(True)
|
||||
|
@ -237,50 +243,46 @@ class InstallDialog(QDialog):
|
|||
self.error_box()
|
||||
|
||||
def get_options(self):
|
||||
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()
|
||||
self.options.force = self.advanced.ui.force_download_check.isChecked()
|
||||
self.options.ignore_space = self.advanced.ui.ignore_space_check.isChecked()
|
||||
self.options.no_install = self.advanced.ui.download_only_check.isChecked()
|
||||
self.options.platform = self.ui.platform_combo.currentText()
|
||||
self.options.install_prereqs = self.advanced.ui.install_prereqs_check.isChecked()
|
||||
self.options.create_shortcut = self.ui.shortcut_check.isChecked()
|
||||
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()
|
||||
self.__options.force = self.advanced.ui.force_download_check.isChecked()
|
||||
self.__options.ignore_space = self.advanced.ui.ignore_space_check.isChecked()
|
||||
self.__options.no_install = self.advanced.ui.download_only_check.isChecked()
|
||||
self.__options.platform = self.ui.platform_combo.currentText()
|
||||
self.__options.install_prereqs = self.advanced.ui.install_prereqs_check.isChecked()
|
||||
self.__options.create_shortcut = self.ui.shortcut_check.isChecked()
|
||||
if self.selectable_checks:
|
||||
self.options.install_tag = [""]
|
||||
self.__options.install_tag = [""]
|
||||
for cb in self.selectable_checks:
|
||||
if data := cb.isChecked():
|
||||
# noinspection PyTypeChecker
|
||||
self.options.install_tag.extend(data)
|
||||
self.__options.install_tag.extend(data)
|
||||
|
||||
def get_download_info(self):
|
||||
self.__download = None
|
||||
info_worker = InstallInfoWorker(self.core, self.options)
|
||||
info_worker = InstallInfoWorker(self.core, self.__options)
|
||||
info_worker.signals.result.connect(self.on_worker_result)
|
||||
info_worker.signals.failed.connect(self.on_worker_failed)
|
||||
info_worker.signals.finished.connect(self.on_worker_finished)
|
||||
self.worker_running = True
|
||||
self.threadpool.start(info_worker)
|
||||
|
||||
def __on_verify(self):
|
||||
def action_handler(self):
|
||||
self.error_box()
|
||||
message = self.tr("Updating...")
|
||||
self.ui.download_size_text.setText(message)
|
||||
self.ui.download_size_text.setStyleSheet("font-style: italic; font-weight: normal")
|
||||
self.ui.install_size_text.setText(message)
|
||||
self.ui.install_size_text.setStyleSheet("font-style: italic; font-weight: normal")
|
||||
self.ui.cancel_button.setEnabled(False)
|
||||
self.ui.verify_button.setEnabled(False)
|
||||
self.ui.install_button.setEnabled(False)
|
||||
self.setActive(True)
|
||||
self.options_changed = False
|
||||
self.get_options()
|
||||
self.get_download_info()
|
||||
|
||||
def option_changed(self, path) -> Tuple[bool, str, int]:
|
||||
self.options_changed = True
|
||||
self.ui.install_button.setEnabled(False)
|
||||
self.ui.verify_button.setEnabled(not self.worker_running)
|
||||
self.accept_button.setEnabled(False)
|
||||
self.action_button.setEnabled(not self.active())
|
||||
return True, path, IndicatorReasonsCommon.VALID
|
||||
|
||||
def save_install_edit(self, path: str):
|
||||
|
@ -291,33 +293,18 @@ class InstallDialog(QDialog):
|
|||
|
||||
def non_reload_option_changed(self, option: str):
|
||||
if option == "download_only":
|
||||
self.options.no_install = self.advanced.ui.download_only_check.isChecked()
|
||||
self.__options.no_install = self.advanced.ui.download_only_check.isChecked()
|
||||
elif option == "shortcut":
|
||||
QSettings().setValue("create_shortcut", self.ui.shortcut_check.isChecked())
|
||||
self.options.create_shortcut = self.ui.shortcut_check.isChecked()
|
||||
self.__options.create_shortcut = self.ui.shortcut_check.isChecked()
|
||||
elif option == "install_prereqs":
|
||||
self.options.install_prereqs = self.advanced.ui.install_prereqs_check.isChecked()
|
||||
|
||||
def __on_cancel(self):
|
||||
if self.config_tags is not None:
|
||||
config_helper.add_option(self.rgame.app_name, 'install_tags', ','.join(self.config_tags))
|
||||
else:
|
||||
# lk: this is purely for cleaning any install tags we might have added erroneously to the config
|
||||
config_helper.remove_option(self.rgame.app_name, 'install_tags')
|
||||
|
||||
self.__download = None
|
||||
self.reject_close = False
|
||||
self.close()
|
||||
|
||||
def __on_install(self):
|
||||
self.reject_close = False
|
||||
self.close()
|
||||
self.__options.install_prereqs = self.advanced.ui.install_prereqs_check.isChecked()
|
||||
|
||||
@staticmethod
|
||||
def same_platform(download: InstallDownloadModel) -> bool:
|
||||
platform = download.igame.platform
|
||||
if pf.system() == "Windows":
|
||||
return platform == "Windows" or platform == "Win32"
|
||||
return platform in {"Windows", "Win32"}
|
||||
elif pf.system() == "Darwin":
|
||||
return platform == "Mac"
|
||||
else:
|
||||
|
@ -325,6 +312,7 @@ class InstallDialog(QDialog):
|
|||
|
||||
@pyqtSlot(InstallDownloadModel)
|
||||
def on_worker_result(self, download: InstallDownloadModel):
|
||||
self.setActive(False)
|
||||
self.__download = download
|
||||
download_size = download.analysis.dl_size
|
||||
install_size = download.analysis.install_size
|
||||
|
@ -332,14 +320,13 @@ class InstallDialog(QDialog):
|
|||
if download_size or (not download_size and (download.game.is_dlc or download.repair)):
|
||||
self.ui.download_size_text.setText(format_size(download_size))
|
||||
self.ui.download_size_text.setStyleSheet("font-style: normal; font-weight: bold")
|
||||
self.ui.install_button.setEnabled(not self.options_changed)
|
||||
self.accept_button.setEnabled(not self.options_changed)
|
||||
else:
|
||||
self.ui.install_size_text.setText(self.tr("Game already installed"))
|
||||
self.ui.install_size_text.setStyleSheet("font-style: italics; font-weight: normal")
|
||||
self.ui.install_size_text.setText(format_size(install_size))
|
||||
self.ui.install_size_text.setStyleSheet("font-style: normal; font-weight: bold")
|
||||
self.ui.verify_button.setEnabled(self.options_changed)
|
||||
self.ui.cancel_button.setEnabled(True)
|
||||
self.action_button.setEnabled(self.options_changed)
|
||||
has_prereqs = bool(download.igame.prereq_info) and not download.igame.prereq_info.get("installed", False)
|
||||
if has_prereqs:
|
||||
prereq_name = download.igame.prereq_info.get("name", "")
|
||||
|
@ -352,18 +339,19 @@ class InstallDialog(QDialog):
|
|||
self.advanced.ui.install_prereqs_label.setEnabled(has_prereqs)
|
||||
self.advanced.ui.install_prereqs_check.setEnabled(has_prereqs)
|
||||
self.advanced.ui.install_prereqs_check.setChecked(has_prereqs and self.same_platform(download))
|
||||
if self.options.silent:
|
||||
self.close()
|
||||
if self.__options.silent:
|
||||
self.accept()
|
||||
|
||||
def on_worker_failed(self, message: str):
|
||||
self.setActive(False)
|
||||
error_text = self.tr("Error")
|
||||
self.ui.download_size_text.setText(error_text)
|
||||
self.ui.install_size_text.setText(error_text)
|
||||
self.error_box(error_text, message)
|
||||
self.ui.verify_button.setEnabled(self.options_changed)
|
||||
self.ui.cancel_button.setEnabled(True)
|
||||
if self.options.silent:
|
||||
self.show()
|
||||
self.action_button.setEnabled(self.options_changed)
|
||||
self.accept_button.setEnabled(False)
|
||||
if self.__options.silent:
|
||||
self.open()
|
||||
|
||||
def error_box(self, label: str = "", message: str = ""):
|
||||
self.ui.warning_label.setVisible(bool(label))
|
||||
|
@ -371,25 +359,23 @@ class InstallDialog(QDialog):
|
|||
self.ui.warning_text.setVisible(bool(message))
|
||||
self.ui.warning_text.setText(message)
|
||||
|
||||
def on_worker_finished(self):
|
||||
self.worker_running = False
|
||||
def done_handler(self):
|
||||
self.threadpool.clear()
|
||||
self.threadpool.waitForDone()
|
||||
self.result_ready.emit(self.__queue_item)
|
||||
|
||||
# lk: happens when close() is called, also when top right 'X' is pressed.
|
||||
# lk: reject any events not coming from the buttons in case the WM
|
||||
# lk: doesn't honor the window hints
|
||||
def closeEvent(self, a0: QCloseEvent) -> None:
|
||||
if self.reject_close:
|
||||
a0.ignore()
|
||||
else:
|
||||
self.threadpool.clear()
|
||||
self.threadpool.waitForDone()
|
||||
self.result_ready.emit(InstallQueueItemModel(options=self.options, download=self.__download))
|
||||
super(InstallDialog, self).closeEvent(a0)
|
||||
# lk: __download is already set at this point so just do nothing.
|
||||
def accept_handler(self):
|
||||
self.__queue_item = InstallQueueItemModel(options=self.__options, download=self.__download)
|
||||
|
||||
def keyPressEvent(self, e: QKeyEvent) -> None:
|
||||
if e.key() == Qt.Key_Escape:
|
||||
e.accept()
|
||||
self.__on_cancel()
|
||||
def reject_handler(self):
|
||||
# FIXME: This is implemented through the selective downloads dialog now. remove soon
|
||||
# if self.config_tags is not None:
|
||||
# config_helper.set_option(self.rgame.app_name, 'install_tags', ','.join(self.config_tags))
|
||||
# else:
|
||||
# # lk: this is purely for cleaning any install tags we might have added erroneously to the config
|
||||
# config_helper.remove_option(self.rgame.app_name, 'install_tags')
|
||||
self.__queue_item = InstallQueueItemModel(options=self.__options, download=None)
|
||||
|
||||
|
||||
class TagCheckBox(QCheckBox):
|
||||
|
|
|
@ -49,17 +49,14 @@ class LaunchDialog(BaseDialog):
|
|||
def login(self):
|
||||
can_launch = True
|
||||
try:
|
||||
if self.args.offline:
|
||||
pass
|
||||
else:
|
||||
if not self.args.offline:
|
||||
# Force an update check and notice in case there are API changes
|
||||
# self.core.check_for_updates(force=True)
|
||||
# self.core.force_show_update = True
|
||||
if self.core.login(force_refresh=True):
|
||||
logger.info("You are logged in")
|
||||
self.login_dialog.close()
|
||||
else:
|
||||
if not self.core.login(force_refresh=True):
|
||||
raise ValueError("You are not logged in. Opening login window.")
|
||||
logger.info("You are logged in")
|
||||
self.login_dialog.close()
|
||||
except ValueError as e:
|
||||
logger.info(str(e))
|
||||
# Do not set parent, because it won't show a task bar icon
|
||||
|
|
|
@ -143,11 +143,10 @@ class LoginDialog(BaseDialog):
|
|||
|
||||
def login_successful(self):
|
||||
try:
|
||||
if self.core.login():
|
||||
self.logged_in = True
|
||||
self.accept()
|
||||
else:
|
||||
if not self.core.login():
|
||||
raise ValueError("Login failed.")
|
||||
self.logged_in = True
|
||||
self.accept()
|
||||
except Exception as e:
|
||||
logger.error(str(e))
|
||||
self.core.lgd.invalidate_userdata()
|
||||
|
|
|
@ -92,9 +92,7 @@ class ImportLogin(QFrame):
|
|||
|
||||
def do_login(self):
|
||||
self.ui.status_label.setText(self.tr("Loading..."))
|
||||
if os.name == "nt":
|
||||
pass
|
||||
else:
|
||||
if os.name != "nt":
|
||||
logger.info("Using EGL appdata path at %s", {self.egl_appdata})
|
||||
self.core.egl.appdata_path = self.egl_appdata
|
||||
try:
|
||||
|
|
108
rare/components/dialogs/selective_dialog.py
Normal file
108
rare/components/dialogs/selective_dialog.py
Normal file
|
@ -0,0 +1,108 @@
|
|||
from typing import List, Union, Optional
|
||||
|
||||
from PyQt5.QtCore import pyqtSignal
|
||||
from PyQt5.QtWidgets import (
|
||||
QLabel,
|
||||
QVBoxLayout,
|
||||
QCheckBox,
|
||||
QLayout, QGroupBox,
|
||||
)
|
||||
from legendary.utils.selective_dl import get_sdl_appname
|
||||
|
||||
from rare.models.game import RareGame
|
||||
from rare.models.install import SelectiveDownloadsModel
|
||||
from rare.widgets.dialogs import ButtonDialog, dialog_title_game
|
||||
from rare.utils.misc import icon
|
||||
|
||||
|
||||
class SelectiveDialog(ButtonDialog):
|
||||
result_ready = pyqtSignal(RareGame, SelectiveDownloadsModel)
|
||||
|
||||
def __init__(self, rgame: RareGame, parent=None):
|
||||
super(SelectiveDialog, self).__init__(parent=parent)
|
||||
header = self.tr("Optional downloads for")
|
||||
self.setWindowTitle(dialog_title_game(header, rgame.app_title))
|
||||
|
||||
title_label = QLabel(f"<h4>{dialog_title_game(header, rgame.app_title)}</h4>", self)
|
||||
|
||||
self.core = rgame.core
|
||||
self.rgame = rgame
|
||||
|
||||
selectable_group = QGroupBox(self.tr("Optional downloads"), self)
|
||||
self.selectable_layout = QVBoxLayout(selectable_group)
|
||||
self.selectable_layout.setSpacing(0)
|
||||
|
||||
self.selectable_checks: List[TagCheckBox] = []
|
||||
self.config_tags: Optional[List[str]] = None
|
||||
|
||||
layout = QVBoxLayout()
|
||||
layout.setSizeConstraint(QLayout.SetFixedSize)
|
||||
layout.addWidget(title_label)
|
||||
layout.addWidget(selectable_group)
|
||||
|
||||
self.setCentralLayout(layout)
|
||||
|
||||
self.accept_button.setText(self.tr("Verify"))
|
||||
self.accept_button.setIcon(icon("fa.check"))
|
||||
|
||||
self.options: SelectiveDownloadsModel = SelectiveDownloadsModel(rgame.app_name)
|
||||
|
||||
config_disable_sdl = self.core.lgd.config.getboolean(self.rgame.app_name, "disable_sdl", fallback=False)
|
||||
sdl_name = get_sdl_appname(self.rgame.app_name)
|
||||
if not config_disable_sdl and sdl_name is not None:
|
||||
self.create_sdl_list()
|
||||
else:
|
||||
self.options.accepted = True
|
||||
self.accept()
|
||||
|
||||
def create_sdl_list(self):
|
||||
platform = self.rgame.igame.platform
|
||||
for cb in self.selectable_checks:
|
||||
cb.disconnect()
|
||||
cb.deleteLater()
|
||||
self.selectable_checks.clear()
|
||||
|
||||
if config_tags := self.core.lgd.config.get(self.rgame.app_name, "install_tags", fallback=None):
|
||||
self.config_tags = config_tags.split(",")
|
||||
config_disable_sdl = self.core.lgd.config.getboolean(self.rgame.app_name, "disable_sdl", fallback=False)
|
||||
sdl_name = get_sdl_appname(self.rgame.app_name)
|
||||
if not config_disable_sdl and sdl_name is not None:
|
||||
sdl_data = self.core.get_sdl_data(sdl_name, platform=platform)
|
||||
if sdl_data:
|
||||
for tag, info in sdl_data.items():
|
||||
cb = TagCheckBox(info["name"].strip(), info["description"].strip(), info["tags"])
|
||||
if tag == "__required":
|
||||
cb.setChecked(True)
|
||||
cb.setDisabled(True)
|
||||
if self.config_tags is not None:
|
||||
if all(elem in self.config_tags for elem in info["tags"]):
|
||||
cb.setChecked(True)
|
||||
self.selectable_layout.addWidget(cb)
|
||||
self.selectable_checks.append(cb)
|
||||
|
||||
def done_handler(self):
|
||||
self.result_ready.emit(self.rgame, self.options)
|
||||
|
||||
def accept_handler(self):
|
||||
install_tag = [""]
|
||||
for cb in self.selectable_checks:
|
||||
if data := cb.isChecked():
|
||||
# noinspection PyTypeChecker
|
||||
install_tag.extend(data)
|
||||
self.options.accepted = True
|
||||
self.options.install_tag = install_tag
|
||||
|
||||
def reject_handler(self):
|
||||
self.options.accepted = False
|
||||
self.options.install_tag = None
|
||||
|
||||
|
||||
class TagCheckBox(QCheckBox):
|
||||
def __init__(self, text, desc, tags: List[str], parent=None):
|
||||
super(TagCheckBox, self).__init__(parent)
|
||||
self.setText(text)
|
||||
self.setToolTip(desc)
|
||||
self.tags = tags
|
||||
|
||||
def isChecked(self) -> Union[bool, List[str]]:
|
||||
return self.tags if super(TagCheckBox, self).isChecked() else False
|
|
@ -6,7 +6,7 @@ from PyQt5.QtWidgets import (
|
|||
QVBoxLayout,
|
||||
QCheckBox,
|
||||
QHBoxLayout,
|
||||
QPushButton,
|
||||
QPushButton, QLayout,
|
||||
)
|
||||
from legendary.utils.selective_dl import get_sdl_appname
|
||||
|
||||
|
@ -24,8 +24,8 @@ class UninstallDialog(QDialog):
|
|||
self.setWindowFlags(Qt.Dialog | Qt.CustomizeWindowHint | Qt.WindowTitleHint)
|
||||
header = self.tr("Uninstall")
|
||||
self.setWindowTitle(f'{header} "{rgame.app_title}" - {QCoreApplication.instance().applicationName()}')
|
||||
self.info_text = QLabel(
|
||||
self.tr("Do you really want to uninstall <b>{}</b>?").format(rgame.app_title)
|
||||
self.title_label = QLabel(
|
||||
self.tr("<h4>Do you really want to uninstall <b>{}</b>?</h4>").format(rgame.app_title)
|
||||
)
|
||||
|
||||
self.keep_files = QCheckBox(self.tr("Keep game files."))
|
||||
|
@ -52,14 +52,13 @@ class UninstallDialog(QDialog):
|
|||
button_layout.addStretch(1)
|
||||
button_layout.addWidget(self.uninstall_button)
|
||||
|
||||
layout = QVBoxLayout()
|
||||
layout.addWidget(self.info_text)
|
||||
layout = QVBoxLayout(self)
|
||||
layout.setSizeConstraint(QLayout.SetFixedSize)
|
||||
layout.addWidget(self.title_label)
|
||||
layout.addLayout(form_layout)
|
||||
layout.addLayout(button_layout)
|
||||
|
||||
self.setLayout(layout)
|
||||
|
||||
if get_sdl_appname(rgame.app_name) is not None:
|
||||
if rgame.sdl_name is not None:
|
||||
self.keep_config.setChecked(True)
|
||||
|
||||
self.options: UninstallOptionsModel = options
|
||||
|
|
|
@ -106,10 +106,10 @@ class MainWindow(QMainWindow):
|
|||
except ModuleNotFoundError:
|
||||
logger.warning("Discord RPC module not found")
|
||||
|
||||
self.timer = QTimer()
|
||||
self.timer.setInterval(1000)
|
||||
self.timer.timeout.connect(self.timer_finished)
|
||||
self.timer.start()
|
||||
self.singleton_timer = QTimer(self)
|
||||
self.singleton_timer.setInterval(1000)
|
||||
self.singleton_timer.timeout.connect(self.timer_finished)
|
||||
self.singleton_timer.start()
|
||||
|
||||
self.tray_icon: TrayIcon = TrayIcon(self)
|
||||
self.tray_icon.exit_app.connect(self.__on_exit_app)
|
||||
|
@ -193,13 +193,12 @@ class MainWindow(QMainWindow):
|
|||
def timer_finished(self):
|
||||
file_path = lock_file()
|
||||
if os.path.exists(file_path):
|
||||
file = open(file_path, "r")
|
||||
action = file.read()
|
||||
file.close()
|
||||
with open(file_path, "r") as file:
|
||||
action = file.read()
|
||||
if action.startswith("show"):
|
||||
self.show()
|
||||
os.remove(file_path)
|
||||
self.timer.start()
|
||||
self.singleton_timer.start()
|
||||
|
||||
@pyqtSlot()
|
||||
@pyqtSlot(int)
|
||||
|
@ -258,7 +257,7 @@ class MainWindow(QMainWindow):
|
|||
e.ignore()
|
||||
return
|
||||
# FIXME: End of FIXME
|
||||
self.timer.stop()
|
||||
self.singleton_timer.stop()
|
||||
self.tray_icon.deleteLater()
|
||||
self.hide()
|
||||
self.exit_app.emit(self.__exit_code)
|
||||
|
|
|
@ -146,7 +146,7 @@ class GamesTab(QStackedWidget):
|
|||
def update_count_games_label(self):
|
||||
self.head_bar.set_games_count(
|
||||
len([game for game in self.rcore.games if game.is_installed]),
|
||||
len([game for game in self.rcore.games])
|
||||
len(list(self.rcore.games)),
|
||||
)
|
||||
|
||||
def setup_game_list(self):
|
||||
|
|
|
@ -13,15 +13,15 @@ from PyQt5.QtWidgets import (
|
|||
QMessageBox,
|
||||
QGroupBox,
|
||||
QVBoxLayout,
|
||||
QSpacerItem,
|
||||
QSpacerItem, QFormLayout,
|
||||
)
|
||||
from legendary.models.game import SaveGameStatus
|
||||
|
||||
from rare.models.game import RareGame
|
||||
from rare.shared import RareCore
|
||||
from rare.shared.workers.wine_resolver import WineResolver
|
||||
from rare.ui.components.tabs.games.game_info.cloud_widget import Ui_CloudWidget
|
||||
from rare.ui.components.tabs.games.game_info.sync_widget import Ui_SyncWidget
|
||||
from rare.ui.components.tabs.games.game_info.cloud_settings_widget import Ui_CloudSettingsWidget
|
||||
from rare.ui.components.tabs.games.game_info.cloud_sync_widget import Ui_CloudSyncWidget
|
||||
from rare.utils.misc import icon
|
||||
from rare.widgets.indicator_edit import PathEdit, IndicatorReasonsCommon
|
||||
from rare.widgets.loading_widget import LoadingWidget
|
||||
|
@ -35,7 +35,7 @@ class CloudSaves(QWidget, SideTabContents):
|
|||
super(CloudSaves, self).__init__(parent=parent)
|
||||
|
||||
self.sync_widget = QWidget(self)
|
||||
self.sync_ui = Ui_SyncWidget()
|
||||
self.sync_ui = Ui_CloudSyncWidget()
|
||||
self.sync_ui.setupUi(self.sync_widget)
|
||||
|
||||
self.info_label = QLabel(self.tr("<b>This game doesn't support cloud saves</b>"))
|
||||
|
@ -56,7 +56,7 @@ class CloudSaves(QWidget, SideTabContents):
|
|||
self.rgame: RareGame = None
|
||||
|
||||
self.cloud_widget = QGroupBox(self)
|
||||
self.cloud_ui = Ui_CloudWidget()
|
||||
self.cloud_ui = Ui_CloudSettingsWidget()
|
||||
self.cloud_ui.setupUi(self.cloud_widget)
|
||||
|
||||
self.cloud_save_path_edit = PathEdit(
|
||||
|
@ -66,16 +66,20 @@ class CloudSaves(QWidget, SideTabContents):
|
|||
edit_func=self.edit_save_path,
|
||||
save_func=self.save_save_path,
|
||||
)
|
||||
self.cloud_ui.cloud_layout.addRow(QLabel(self.tr("Save path")), self.cloud_save_path_edit)
|
||||
self.cloud_ui.main_layout.setWidget(
|
||||
self.cloud_ui.main_layout.getWidgetPosition(self.cloud_ui.path_label)[0],
|
||||
QFormLayout.FieldRole,
|
||||
self.cloud_save_path_edit
|
||||
)
|
||||
|
||||
self.compute_save_path_button = QPushButton(icon("fa.magic"), self.tr("Calculate path"))
|
||||
self.compute_save_path_button.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Fixed)
|
||||
self.compute_save_path_button.clicked.connect(self.compute_save_path)
|
||||
self.cloud_ui.cloud_layout.addRow(None, self.compute_save_path_button)
|
||||
self.cloud_ui.main_layout.addRow(None, self.compute_save_path_button)
|
||||
|
||||
self.cloud_ui.cloud_sync.stateChanged.connect(
|
||||
self.cloud_ui.sync_check.stateChanged.connect(
|
||||
lambda: self.settings.setValue(
|
||||
f"{self.rgame.app_name}/auto_sync_cloud", self.cloud_ui.cloud_sync.isChecked()
|
||||
f"{self.rgame.app_name}/auto_sync_cloud", self.cloud_ui.sync_check.isChecked()
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -139,7 +143,7 @@ class CloudSaves(QWidget, SideTabContents):
|
|||
self.compute_save_path_button.setDisabled(False)
|
||||
if path and not os.path.exists(path):
|
||||
try:
|
||||
os.makedirs(path)
|
||||
os.makedirs(path, exist_ok=True)
|
||||
except PermissionError:
|
||||
self.cloud_save_path_edit.setText("")
|
||||
QMessageBox.warning(
|
||||
|
@ -172,7 +176,7 @@ class CloudSaves(QWidget, SideTabContents):
|
|||
self.sync_ui.age_label_local.setText("None")
|
||||
self.sync_ui.date_info_remote.setText("None")
|
||||
self.sync_ui.age_label_remote.setText("None")
|
||||
self.cloud_ui.cloud_sync.setChecked(False)
|
||||
self.cloud_ui.sync_check.setChecked(False)
|
||||
self.cloud_save_path_edit.setText("")
|
||||
return
|
||||
|
||||
|
@ -203,9 +207,9 @@ class CloudSaves(QWidget, SideTabContents):
|
|||
self.sync_ui.upload_button.setDisabled(not dt_local)
|
||||
self.sync_ui.download_button.setDisabled(not dt_remote)
|
||||
|
||||
self.cloud_ui.cloud_sync.blockSignals(True)
|
||||
self.cloud_ui.cloud_sync.setChecked(self.rgame.auto_sync_saves)
|
||||
self.cloud_ui.cloud_sync.blockSignals(False)
|
||||
self.cloud_ui.sync_check.blockSignals(True)
|
||||
self.cloud_ui.sync_check.setChecked(self.rgame.auto_sync_saves)
|
||||
self.cloud_ui.sync_check.blockSignals(False)
|
||||
|
||||
self.cloud_save_path_edit.setText(self.rgame.save_path if self.rgame.save_path else "")
|
||||
if platform.system() == "Windows" and not self.rgame.save_path:
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
from typing import Optional, List
|
||||
|
||||
from PyQt5.QtCore import Qt, pyqtSlot, pyqtSignal
|
||||
from PyQt5.QtGui import QShowEvent
|
||||
from PyQt5.QtWidgets import QFrame, QMessageBox, QToolBox
|
||||
|
||||
from rare.models.game import RareGame
|
||||
|
@ -37,6 +38,14 @@ class GameDlcWidget(QFrame):
|
|||
@pyqtSlot()
|
||||
def __update(self):
|
||||
self.ui.action_button.setEnabled(self.rdlc.is_idle)
|
||||
self.image.setPixmap(self.rdlc.pixmap)
|
||||
|
||||
def showEvent(self, a0: QShowEvent) -> None:
|
||||
if a0.spontaneous():
|
||||
return super().showEvent(a0)
|
||||
if self.rdlc.pixmap.isNull():
|
||||
self.rdlc.load_pixmap()
|
||||
super().showEvent(a0)
|
||||
|
||||
|
||||
class InstalledGameDlcWidget(GameDlcWidget):
|
||||
|
|
|
@ -16,6 +16,8 @@ from PyQt5.QtWidgets import (
|
|||
QWidgetAction,
|
||||
)
|
||||
|
||||
from rare.models.install import SelectiveDownloadsModel
|
||||
from rare.components.dialogs.selective_dialog import SelectiveDialog
|
||||
from rare.models.game import RareGame
|
||||
from rare.shared import RareCore
|
||||
from rare.shared.workers import VerifyWorker, MoveWorker
|
||||
|
@ -42,12 +44,12 @@ class GameInfo(QWidget, SideTabContents):
|
|||
self.ui.uninstall_button.setObjectName("UninstallButton")
|
||||
|
||||
self.ui.install_button.setIcon(icon("ri.install-line"))
|
||||
self.ui.import_button.setIcon(icon("mdi.file-import"))
|
||||
self.ui.import_button.setIcon(icon("mdi.application-import"))
|
||||
|
||||
self.ui.modify_button.setIcon(icon("fa.gear"))
|
||||
self.ui.verify_button.setIcon(icon("fa.check"))
|
||||
self.ui.repair_button.setIcon(icon("fa.wrench"))
|
||||
self.ui.move_button.setIcon(icon("mdi.folder-move"))
|
||||
self.ui.move_button.setIcon(icon("mdi.folder-move-outline"))
|
||||
self.ui.uninstall_button.setIcon(icon("ri.uninstall-line"))
|
||||
|
||||
self.rcore = RareCore.instance()
|
||||
|
@ -162,9 +164,22 @@ class GameInfo(QWidget, SideTabContents):
|
|||
self.tr("Installation path for <b>{}</b> does not exist. Cannot continue.").format(self.rgame.app_title),
|
||||
)
|
||||
return
|
||||
self.verify_game(self.rgame)
|
||||
if self.rgame.sdl_name is not None:
|
||||
selective_dialog = SelectiveDialog(
|
||||
self.rgame, parent=self
|
||||
)
|
||||
selective_dialog.result_ready.connect(self.verify_game)
|
||||
selective_dialog.open()
|
||||
else:
|
||||
self.verify_game(self.rgame)
|
||||
|
||||
def verify_game(self, rgame: RareGame):
|
||||
@pyqtSlot(RareGame, SelectiveDownloadsModel)
|
||||
def verify_game(self, rgame: RareGame, sdl_model: SelectiveDownloadsModel = None):
|
||||
if sdl_model is not None:
|
||||
if not sdl_model.accepted or sdl_model.install_tag is None:
|
||||
return
|
||||
self.core.lgd.config.set(rgame.app_name, "install_tags", ','.join(sdl_model.install_tag))
|
||||
self.core.lgd.save_config()
|
||||
worker = VerifyWorker(self.core, self.args, rgame)
|
||||
worker.signals.progress.connect(self.__on_verify_progress)
|
||||
worker.signals.result.connect(self.__on_verify_result)
|
||||
|
@ -378,7 +393,7 @@ class GameInfo(QWidget, SideTabContents):
|
|||
self.ui.install_button.setText(self.tr("Link/Launch"))
|
||||
self.ui.game_actions_stack.setCurrentWidget(self.ui.uninstalled_page)
|
||||
else:
|
||||
self.ui.install_button.setText(self.tr("Install Game"))
|
||||
self.ui.install_button.setText(self.tr("Install"))
|
||||
|
||||
self.move_game_pop_up.update_game(rgame)
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ class EnvVars(QGroupBox):
|
|||
layout.addWidget(self.table_view)
|
||||
|
||||
def keyPressEvent(self, e):
|
||||
if e.key() == Qt.Key_Delete or e.key() == Qt.Key_Backspace:
|
||||
if e.key() in {Qt.Key_Delete, Qt.Key_Backspace}:
|
||||
indexes = self.table_view.selectedIndexes()
|
||||
if not len(indexes):
|
||||
return
|
||||
|
|
|
@ -97,7 +97,7 @@ class EnvVarsTableModel(QAbstractTableModel):
|
|||
return value == match.group(0)
|
||||
|
||||
def data(self, index: QModelIndex, role: int = Qt.DisplayRole) -> Any:
|
||||
if role == Qt.DisplayRole or role == Qt.EditRole:
|
||||
if role in {Qt.DisplayRole, Qt.EditRole}:
|
||||
if index.row() == self.__data_length():
|
||||
return ""
|
||||
if index.column() == 0:
|
||||
|
|
|
@ -14,18 +14,22 @@ from PyQt5.QtNetwork import QLocalServer, QLocalSocket
|
|||
from PyQt5.QtWidgets import QApplication
|
||||
from legendary.models.game import SaveGameStatus
|
||||
|
||||
from rare.components.dialogs.cloud_save_dialog import CloudSaveDialog
|
||||
from rare.lgndr.core import LegendaryCore
|
||||
from rare.models.base_game import RareGameSlim
|
||||
from rare.models.launcher import ErrorModel, Actions, FinishedModel, BaseModel, StateChangedModel
|
||||
from rare.widgets.rare_app import RareApp, RareAppException
|
||||
from .console import Console
|
||||
from .cloud_sync_dialog import CloudSyncDialog, CloudSyncDialogResult
|
||||
from .console_dialog import ConsoleDialog
|
||||
from .lgd_helper import get_launch_args, InitArgs, get_configured_process, LaunchArgs, GameArgsError
|
||||
|
||||
DETACHED_APP_NAMES = [
|
||||
"0a2d9f6403244d12969e11da6713137b" # Fall Guys
|
||||
"Fortnite"
|
||||
]
|
||||
DETACHED_APP_NAMES = {
|
||||
"0a2d9f6403244d12969e11da6713137b", # Fall Guys
|
||||
"Fortnite",
|
||||
"afdb5a85efcc45d8ae8e406e2121d81c", # Fortnite Battle Royale
|
||||
"09e442f830a341f698b4da42abd98c9b", # Fortnite Festival
|
||||
"d8f7763e07d74c209d760a679f9ed6ac", # Lego Fortnite
|
||||
"Fortnite_Studio", # Unreal Editor for Fortnite
|
||||
}
|
||||
|
||||
|
||||
class PreLaunchThread(QRunnable):
|
||||
|
@ -37,30 +41,29 @@ class PreLaunchThread(QRunnable):
|
|||
|
||||
def __init__(self, core: LegendaryCore, args: InitArgs, rgame: RareGameSlim, sync_action=None):
|
||||
super(PreLaunchThread, self).__init__()
|
||||
self.logger = getLogger(type(self).__name__)
|
||||
self.core = core
|
||||
self.signals = self.Signals()
|
||||
self.logger = getLogger(type(self).__name__)
|
||||
self.args = args
|
||||
self.rgame = rgame
|
||||
self.sync_action = sync_action
|
||||
|
||||
def run(self) -> None:
|
||||
self.logger.info(f"Sync action: {self.sync_action}")
|
||||
if self.sync_action == CloudSaveDialog.UPLOAD:
|
||||
if self.sync_action == CloudSyncDialogResult.UPLOAD:
|
||||
self.rgame.upload_saves(False)
|
||||
elif self.sync_action == CloudSaveDialog.DOWNLOAD:
|
||||
elif self.sync_action == CloudSyncDialogResult.DOWNLOAD:
|
||||
self.rgame.download_saves(False)
|
||||
else:
|
||||
self.logger.info("No sync action")
|
||||
|
||||
args = self.prepare_launch(self.args)
|
||||
if not args:
|
||||
if args := self.prepare_launch(self.args):
|
||||
self.signals.ready_to_launch.emit(args)
|
||||
else:
|
||||
return
|
||||
self.signals.ready_to_launch.emit(args)
|
||||
|
||||
def prepare_launch(self, args: InitArgs) -> Optional[LaunchArgs]:
|
||||
try:
|
||||
launch_args = get_launch_args(self.core, args)
|
||||
launch_args = get_launch_args(self.rgame, args)
|
||||
except Exception as e:
|
||||
self.signals.error_occurred.emit(str(e))
|
||||
return None
|
||||
|
@ -121,7 +124,7 @@ class RareLauncher(RareApp):
|
|||
def __init__(self, args: InitArgs):
|
||||
super(RareLauncher, self).__init__(args, f"{type(self).__name__}_{args.app_name}_{{0}}.log")
|
||||
self.socket: Optional[QLocalSocket] = None
|
||||
self.console: Optional[Console] = None
|
||||
self.console: Optional[ConsoleDialog] = None
|
||||
self.game_process: QProcess = QProcess(self)
|
||||
self.server: QLocalServer = QLocalServer(self)
|
||||
|
||||
|
@ -142,7 +145,7 @@ class RareLauncher(RareApp):
|
|||
self.load_translator(lang)
|
||||
|
||||
if QSettings().value("show_console", False, bool):
|
||||
self.console = Console()
|
||||
self.console = ConsoleDialog()
|
||||
self.console.show()
|
||||
|
||||
self.game_process.finished.connect(self.__process_finished)
|
||||
|
@ -213,15 +216,22 @@ class RareLauncher(RareApp):
|
|||
state, (dt_local, dt_remote) = self.rgame.save_game_state
|
||||
|
||||
if state == SaveGameStatus.LOCAL_NEWER and not self.no_sync_on_exit:
|
||||
action = CloudSaveDialog.UPLOAD
|
||||
action = CloudSyncDialogResult.UPLOAD
|
||||
self.__check_saved_finished(exit_code, action)
|
||||
else:
|
||||
action = CloudSaveDialog(self.rgame.igame, dt_local, dt_remote).get_action()
|
||||
sync_dialog = CloudSyncDialog(self.rgame.igame, dt_local, dt_remote)
|
||||
sync_dialog.result_ready.connect(lambda a: self.__check_saved_finished(exit_code, a))
|
||||
sync_dialog.open()
|
||||
|
||||
if action == CloudSaveDialog.UPLOAD:
|
||||
@pyqtSlot(int, int)
|
||||
@pyqtSlot(int, CloudSyncDialogResult)
|
||||
def __check_saved_finished(self, exit_code, action):
|
||||
action = CloudSyncDialogResult(action)
|
||||
if action == CloudSyncDialogResult.UPLOAD:
|
||||
if self.console:
|
||||
self.console.log("Uploading saves...")
|
||||
self.rgame.upload_saves()
|
||||
elif action == CloudSaveDialog.DOWNLOAD:
|
||||
elif action == CloudSyncDialogResult.DOWNLOAD:
|
||||
if self.console:
|
||||
self.console.log("Downloading saves...")
|
||||
self.rgame.download_saves()
|
||||
|
@ -326,14 +336,20 @@ class RareLauncher(RareApp):
|
|||
return
|
||||
|
||||
_, (dt_local, dt_remote) = self.rgame.save_game_state
|
||||
dlg = CloudSaveDialog(self.rgame.igame, dt_local, dt_remote)
|
||||
action = dlg.get_action()
|
||||
if action == CloudSaveDialog.CANCEL:
|
||||
sync_dialog = CloudSyncDialog(self.rgame.igame, dt_local, dt_remote)
|
||||
sync_dialog.result_ready.connect(self.__sync_ready)
|
||||
sync_dialog.open()
|
||||
|
||||
@pyqtSlot(int)
|
||||
@pyqtSlot(CloudSyncDialogResult)
|
||||
def __sync_ready(self, action: CloudSyncDialogResult):
|
||||
action = CloudSyncDialogResult(action)
|
||||
if action == CloudSyncDialogResult.CANCEL:
|
||||
self.no_sync_on_exit = True
|
||||
if self.console:
|
||||
if action == CloudSaveDialog.DOWNLOAD:
|
||||
if action == CloudSyncDialogResult.DOWNLOAD:
|
||||
self.console.log("Downloading saves...")
|
||||
elif action == CloudSaveDialog.UPLOAD:
|
||||
elif action == CloudSyncDialogResult.UPLOAD:
|
||||
self.console.log("Uploading saves...")
|
||||
self.start_prepare(action)
|
||||
|
||||
|
|
103
rare/launcher/cloud_sync_dialog.py
Normal file
103
rare/launcher/cloud_sync_dialog.py
Normal file
|
@ -0,0 +1,103 @@
|
|||
import sys
|
||||
from datetime import datetime
|
||||
from enum import IntEnum
|
||||
from logging import getLogger
|
||||
|
||||
from PyQt5.QtCore import pyqtSignal, pyqtSlot
|
||||
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QLabel, QDialog
|
||||
from legendary.core import LegendaryCore
|
||||
from legendary.models.game import InstalledGame
|
||||
|
||||
from rare.ui.components.tabs.games.game_info.cloud_sync_widget import Ui_CloudSyncWidget
|
||||
from rare.utils.misc import icon
|
||||
from rare.widgets.dialogs import ButtonDialog, dialog_title_game
|
||||
|
||||
logger = getLogger("CloudSyncDialog")
|
||||
|
||||
|
||||
class CloudSyncDialogResult(IntEnum):
|
||||
DOWNLOAD = 2
|
||||
UPLOAD = 1
|
||||
CANCEL = 0
|
||||
SKIP = 3
|
||||
|
||||
|
||||
class CloudSyncDialog(ButtonDialog):
|
||||
result_ready: pyqtSignal = pyqtSignal(CloudSyncDialogResult)
|
||||
|
||||
def __init__(self, igame: InstalledGame, dt_local: datetime, dt_remote: datetime, parent=None):
|
||||
super(CloudSyncDialog, self).__init__(parent=parent)
|
||||
header = self.tr("Cloud saves for")
|
||||
self.setWindowTitle(dialog_title_game(header, igame.title))
|
||||
|
||||
title_label = QLabel(f"<h4>{dialog_title_game(header, igame.title)}</h4>", self)
|
||||
|
||||
sync_widget = QWidget(self)
|
||||
self.sync_ui = Ui_CloudSyncWidget()
|
||||
self.sync_ui.setupUi(sync_widget)
|
||||
|
||||
layout = QVBoxLayout()
|
||||
layout.addWidget(title_label)
|
||||
layout.addWidget(sync_widget)
|
||||
|
||||
self.accept_button.setText(self.tr("Skip"))
|
||||
self.accept_button.setIcon(icon("fa.chevron-right"))
|
||||
|
||||
self.setCentralLayout(layout)
|
||||
|
||||
self.status = CloudSyncDialogResult.CANCEL
|
||||
|
||||
newer = self.tr("Newer")
|
||||
if dt_remote and dt_local:
|
||||
self.sync_ui.age_label_local.setText(f"<b>{newer}</b>" if dt_remote < dt_local else " ")
|
||||
self.sync_ui.age_label_remote.setText(f"<b>{newer}</b>" if dt_remote > dt_local else " ")
|
||||
# Set status, if one of them is None
|
||||
elif dt_remote and not dt_local:
|
||||
self.status = CloudSyncDialogResult.DOWNLOAD
|
||||
elif not dt_remote and dt_local:
|
||||
self.status = CloudSyncDialogResult.UPLOAD
|
||||
else:
|
||||
self.status = CloudSyncDialogResult.SKIP
|
||||
|
||||
self.sync_ui.date_info_local.setText(dt_local.strftime("%A, %d. %B %Y %X") if dt_local else "None")
|
||||
self.sync_ui.date_info_remote.setText(dt_remote.strftime("%A, %d. %B %Y %X") if dt_remote else "None")
|
||||
|
||||
self.sync_ui.icon_local.setPixmap(icon("mdi.harddisk", "fa.desktop").pixmap(128, 128))
|
||||
self.sync_ui.icon_remote.setPixmap(icon("mdi.cloud-outline", "ei.cloud").pixmap(128, 128))
|
||||
|
||||
self.sync_ui.upload_button.clicked.connect(self.__on_upload)
|
||||
self.sync_ui.download_button.clicked.connect(self.__on_download)
|
||||
|
||||
if self.status == CloudSyncDialogResult.SKIP:
|
||||
self.accept()
|
||||
|
||||
def __on_upload(self):
|
||||
self.status = CloudSyncDialogResult.UPLOAD
|
||||
self.done(QDialog.Accepted)
|
||||
|
||||
def __on_download(self):
|
||||
self.status = CloudSyncDialogResult.DOWNLOAD
|
||||
self.done(QDialog.Accepted)
|
||||
|
||||
def done_handler(self):
|
||||
self.result_ready.emit(self.status)
|
||||
|
||||
def accept_handler(self):
|
||||
self.status = CloudSyncDialogResult.SKIP
|
||||
|
||||
def reject_handler(self):
|
||||
self.status = CloudSyncDialogResult.CANCEL
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app = QApplication(sys.argv)
|
||||
core = LegendaryCore()
|
||||
|
||||
@pyqtSlot(int)
|
||||
def __callback(status: int):
|
||||
print(repr(CloudSyncDialogResult(status)))
|
||||
|
||||
dlg = CloudSyncDialog(core.get_installed_list()[0], datetime.now(), datetime.strptime("2021,1", "%Y,%M"))
|
||||
dlg.result_ready.connect(__callback)
|
||||
dlg.open()
|
||||
app.exec()
|
|
@ -14,16 +14,16 @@ from PyQt5.QtWidgets import (
|
|||
QSizePolicy, QTableWidgetItem, QHeaderView, QApplication,
|
||||
)
|
||||
|
||||
from rare.ui.components.extra.console_env import Ui_ConsoleEnv
|
||||
from rare.ui.launcher.console_env import Ui_ConsoleEnv
|
||||
|
||||
|
||||
class Console(QDialog):
|
||||
class ConsoleDialog(QDialog):
|
||||
term = pyqtSignal()
|
||||
kill = pyqtSignal()
|
||||
env: QProcessEnvironment
|
||||
|
||||
def __init__(self, parent=None):
|
||||
super(Console, self).__init__(parent=parent)
|
||||
super(ConsoleDialog, self).__init__(parent=parent)
|
||||
self.setAttribute(Qt.WA_DeleteOnClose, True)
|
||||
self.setWindowTitle("Rare - Console")
|
||||
self.setGeometry(0, 0, 640, 480)
|
||||
|
@ -68,7 +68,7 @@ class Console(QDialog):
|
|||
self.accept_close = False
|
||||
|
||||
def show(self) -> None:
|
||||
super(Console, self).show()
|
||||
super(ConsoleDialog, self).show()
|
||||
self.center_window()
|
||||
|
||||
def center_window(self):
|
||||
|
@ -131,7 +131,7 @@ class Console(QDialog):
|
|||
|
||||
def closeEvent(self, a0: QCloseEvent) -> None:
|
||||
if self.accept_close:
|
||||
super(Console, self).closeEvent(a0)
|
||||
super(ConsoleDialog, self).closeEvent(a0)
|
||||
a0.accept()
|
||||
else:
|
||||
self.showMinimized()
|
|
@ -7,10 +7,9 @@ from logging import getLogger
|
|||
from typing import List
|
||||
|
||||
from PyQt5.QtCore import QProcess, QProcessEnvironment
|
||||
from legendary.models.game import InstalledGame, LaunchParameters
|
||||
|
||||
from rare.lgndr.core import LegendaryCore
|
||||
from legendary.models.game import LaunchParameters
|
||||
|
||||
from rare.models.base_game import RareGameSlim
|
||||
|
||||
logger = getLogger("Helper")
|
||||
|
||||
|
@ -55,9 +54,11 @@ class LaunchArgs:
|
|||
return bool(self.executable)
|
||||
|
||||
|
||||
def get_origin_params(core: LegendaryCore, app_name, offline: bool,
|
||||
launch_args: LaunchArgs) -> LaunchArgs:
|
||||
origin_uri = core.get_origin_uri(app_name, offline)
|
||||
def get_origin_params(rgame: RareGameSlim, init_args: InitArgs, launch_args: LaunchArgs) -> LaunchArgs:
|
||||
core = rgame.core
|
||||
app_name = rgame.app_name
|
||||
|
||||
origin_uri = core.get_origin_uri(app_name, init_args.offline)
|
||||
if platform.system() == "Windows":
|
||||
launch_args.executable = origin_uri
|
||||
launch_args.arguments = []
|
||||
|
@ -75,8 +76,7 @@ def get_origin_params(core: LegendaryCore, app_name, offline: bool,
|
|||
|
||||
if os.environ.get("container") == "flatpak":
|
||||
flatpak_command = ["flatpak-spawn", "--host"]
|
||||
for name, value in env.items():
|
||||
flatpak_command.append(f"--env={name}={value}")
|
||||
flatpak_command.extend(f"--env={name}={value}" for name, value in env.items())
|
||||
command = flatpak_command + command
|
||||
else:
|
||||
for name, value in env.items():
|
||||
|
@ -88,24 +88,25 @@ def get_origin_params(core: LegendaryCore, app_name, offline: bool,
|
|||
return launch_args
|
||||
|
||||
|
||||
def get_game_params(core: LegendaryCore, igame: InstalledGame, args: InitArgs,
|
||||
launch_args: LaunchArgs) -> LaunchArgs:
|
||||
def get_game_params(rgame: RareGameSlim, args: InitArgs, launch_args: LaunchArgs) -> LaunchArgs:
|
||||
if not args.offline: # skip for update
|
||||
if not args.skip_update_check and not core.is_noupdate_game(igame.app_name):
|
||||
# print("Checking for updates...")
|
||||
# check updates
|
||||
if not args.skip_update_check and not rgame.core.is_noupdate_game(rgame.app_name):
|
||||
try:
|
||||
latest = core.get_asset(
|
||||
igame.app_name, igame.platform, update=False
|
||||
)
|
||||
latest = rgame.core.get_asset(rgame.app_name, rgame.igame.platform, update=False)
|
||||
except ValueError:
|
||||
raise GameArgsError("Metadata doesn't exist")
|
||||
else:
|
||||
if latest.build_version != igame.version:
|
||||
if latest.build_version != rgame.igame.version:
|
||||
raise GameArgsError("Game is not up to date. Please update first")
|
||||
|
||||
params: LaunchParameters = core.get_launch_parameters(
|
||||
app_name=igame.app_name, offline=args.offline
|
||||
if (not rgame.igame or not rgame.igame.executable) and rgame.game is not None:
|
||||
# override installed game with base title
|
||||
if rgame.is_launchable_addon:
|
||||
app_name = rgame.game.metadata['mainGameItem']['releaseInfo'][0]['appId']
|
||||
rgame.igame = rgame.core.get_installed_game(app_name)
|
||||
|
||||
params: LaunchParameters = rgame.core.get_launch_parameters(
|
||||
app_name=rgame.game.app_name, offline=args.offline, addon_app_name=rgame.igame.app_name
|
||||
)
|
||||
|
||||
full_params = []
|
||||
|
@ -113,8 +114,10 @@ def get_game_params(core: LegendaryCore, igame: InstalledGame, args: InitArgs,
|
|||
|
||||
if os.environ.get("container") == "flatpak":
|
||||
full_params.extend(["flatpak-spawn", "--host"])
|
||||
for name, value in params.environment.items():
|
||||
full_params.append(f"--env={name}={value}")
|
||||
full_params.extend(
|
||||
f"--env={name}={value}"
|
||||
for name, value in params.environment.items()
|
||||
)
|
||||
else:
|
||||
for name, value in params.environment.items():
|
||||
launch_args.environment.insert(name, value)
|
||||
|
@ -134,32 +137,30 @@ def get_game_params(core: LegendaryCore, igame: InstalledGame, args: InitArgs,
|
|||
return launch_args
|
||||
|
||||
|
||||
def get_launch_args(core: LegendaryCore, args: InitArgs = None) -> LaunchArgs:
|
||||
game = core.get_game(args.app_name)
|
||||
igame = core.get_installed_game(args.app_name)
|
||||
def get_launch_args(rgame: RareGameSlim, init_args: InitArgs = None) -> LaunchArgs:
|
||||
|
||||
resp = LaunchArgs()
|
||||
|
||||
if not game:
|
||||
raise GameArgsError(f"Could not find metadata for ")
|
||||
if not rgame.game:
|
||||
raise GameArgsError(f"Could not find metadata for {rgame.app_title}")
|
||||
|
||||
if game.third_party_store == "Origin":
|
||||
args.offline = False
|
||||
if rgame.is_origin:
|
||||
init_args.offline = False
|
||||
else:
|
||||
if not igame:
|
||||
if not rgame.is_installed:
|
||||
raise GameArgsError("Game is not installed or has unsupported format")
|
||||
|
||||
if game.is_dlc:
|
||||
if rgame.is_dlc:
|
||||
raise GameArgsError("Game is a DLC")
|
||||
if not os.path.exists(igame.install_path):
|
||||
if not os.path.exists(rgame.install_path):
|
||||
raise GameArgsError("Game path does not exist")
|
||||
|
||||
if game.third_party_store == "Origin":
|
||||
resp = get_origin_params(core, args.app_name, args.offline, resp)
|
||||
if rgame.is_origin:
|
||||
resp = get_origin_params(rgame, init_args, resp)
|
||||
else:
|
||||
resp = get_game_params(core, igame, args, resp)
|
||||
resp = get_game_params(rgame, init_args, resp)
|
||||
|
||||
pre_cmd, wait = core.get_pre_launch_command(args.app_name)
|
||||
pre_cmd, wait = rgame.core.get_pre_launch_command(init_args.app_name)
|
||||
resp.pre_launch_command, resp.pre_launch_wait = pre_cmd, wait
|
||||
return resp
|
||||
|
||||
|
|
|
@ -97,7 +97,7 @@ def main() -> int:
|
|||
print(f"Rare {__version__} Codename: {__codename__}")
|
||||
return 0
|
||||
|
||||
if args.subparser == "start" or args.subparser == "launch":
|
||||
if args.subparser in {"start", "launch"}:
|
||||
from rare.launcher import launch
|
||||
return launch(args)
|
||||
|
||||
|
|
|
@ -154,14 +154,30 @@ class RareGameBase(QObject):
|
|||
|
||||
@return bool If the game is an Origin game
|
||||
"""
|
||||
return (
|
||||
self.game.metadata.get("customAttributes", {}).get("ThirdPartyManagedApp", {}).get("value") == "Origin"
|
||||
)
|
||||
return self.game.third_party_store in {"Origin", "the EA app"}
|
||||
|
||||
@property
|
||||
def is_overlay(self):
|
||||
return self.app_name == eos.EOSOverlayApp.app_name
|
||||
|
||||
@property
|
||||
def is_dlc(self) -> bool:
|
||||
"""!
|
||||
@brief Property to report if Game is a dlc
|
||||
|
||||
@return bool
|
||||
"""
|
||||
return self.game.is_dlc
|
||||
|
||||
@property
|
||||
def is_launchable_addon(self) -> bool:
|
||||
# lk: the attribute doesn't exist in the currently released version
|
||||
# FIXME: remove after legendary >= 0.20.35
|
||||
try:
|
||||
return self.game.is_launchable_addon
|
||||
except AttributeError:
|
||||
return False
|
||||
|
||||
@property
|
||||
def version(self) -> str:
|
||||
"""!
|
||||
|
@ -192,7 +208,9 @@ class RareGameSlim(RareGameBase):
|
|||
|
||||
@property
|
||||
def is_installed(self) -> bool:
|
||||
return True
|
||||
if self.is_origin:
|
||||
return True
|
||||
return self.igame is not None
|
||||
|
||||
def set_installed(self, installed: bool) -> None:
|
||||
pass
|
||||
|
@ -300,8 +318,7 @@ class RareGameSlim(RareGameBase):
|
|||
@property
|
||||
def is_save_up_to_date(self):
|
||||
status, (_, _) = self.save_game_state
|
||||
return (status == SaveGameStatus.SAME_AGE) \
|
||||
or (status == SaveGameStatus.NO_SAVE)
|
||||
return status in {SaveGameStatus.SAME_AGE, SaveGameStatus.NO_SAVE}
|
||||
|
||||
@property
|
||||
def raw_save_path(self) -> str:
|
||||
|
|
|
@ -376,15 +376,6 @@ class RareGame(RareGameSlim):
|
|||
if not needs and os.path.exists(self.repair_file):
|
||||
os.unlink(self.repair_file)
|
||||
|
||||
@property
|
||||
def is_dlc(self) -> bool:
|
||||
"""!
|
||||
@brief Property to report if Game is a dlc
|
||||
|
||||
@return bool
|
||||
"""
|
||||
return self.game.is_dlc
|
||||
|
||||
@property
|
||||
def is_unreal(self) -> bool:
|
||||
"""!
|
||||
|
@ -411,9 +402,7 @@ class RareGame(RareGameSlim):
|
|||
|
||||
@property
|
||||
def is_ubisoft(self) -> bool:
|
||||
return (
|
||||
self.game.metadata.get("customAttributes", {}).get("partnerLinkType", {}).get("value") == "ubisoft"
|
||||
)
|
||||
return self.game.partner_link_type == "ubisoft"
|
||||
|
||||
@property
|
||||
def folder_name(self) -> str:
|
||||
|
|
|
@ -117,3 +117,18 @@ class UninstallOptionsModel:
|
|||
self.accepted = values[0]
|
||||
self.keep_files = values[1]
|
||||
self.keep_config = values[2]
|
||||
|
||||
|
||||
@dataclass
|
||||
class SelectiveDownloadsModel:
|
||||
app_name: str
|
||||
accepted: bool = None
|
||||
install_tag: Optional[List[str]] = None
|
||||
|
||||
def __bool__(self):
|
||||
return (
|
||||
bool(self.app_name)
|
||||
and (self.accepted is not None)
|
||||
and (self.install_tag is not None)
|
||||
)
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ import json
|
|||
import logging
|
||||
from enum import IntEnum
|
||||
|
||||
from PyQt5.QtCore import QObject, pyqtSignal, QTimer, pyqtSlot
|
||||
from PyQt5.QtCore import QObject, pyqtSignal, QTimer, pyqtSlot, Qt
|
||||
from PyQt5.QtNetwork import QLocalSocket
|
||||
from PyQt5.QtWidgets import QMessageBox
|
||||
from legendary.models.game import Game
|
||||
|
|
|
@ -374,7 +374,7 @@ class RareCore(QObject):
|
|||
|
||||
@property
|
||||
def games(self) -> Iterator[RareGame]:
|
||||
return self.__filter_games(lambda game: not game.is_dlc)
|
||||
return self.__filter_games(lambda game: not game.is_dlc or game.is_launchable_addon)
|
||||
|
||||
@property
|
||||
def installed_games(self) -> Iterator[RareGame]:
|
||||
|
|
|
@ -14,20 +14,20 @@ from PyQt5 import QtCore, QtGui, QtWidgets
|
|||
class Ui_InstallDialog(object):
|
||||
def setupUi(self, InstallDialog):
|
||||
InstallDialog.setObjectName("InstallDialog")
|
||||
InstallDialog.resize(272, 238)
|
||||
InstallDialog.resize(179, 204)
|
||||
InstallDialog.setWindowTitle("InstallDialog")
|
||||
self.install_dialog_layout = QtWidgets.QFormLayout(InstallDialog)
|
||||
self.install_dialog_layout.setLabelAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||
self.install_dialog_layout.setObjectName("install_dialog_layout")
|
||||
self.install_dialog_label = QtWidgets.QLabel(InstallDialog)
|
||||
self.install_dialog_label.setObjectName("install_dialog_label")
|
||||
self.install_dialog_layout.setWidget(0, QtWidgets.QFormLayout.SpanningRole, self.install_dialog_label)
|
||||
self.main_layout = QtWidgets.QFormLayout(InstallDialog)
|
||||
self.main_layout.setLabelAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||
self.main_layout.setObjectName("main_layout")
|
||||
self.title_label = QtWidgets.QLabel(InstallDialog)
|
||||
self.title_label.setObjectName("title_label")
|
||||
self.main_layout.setWidget(0, QtWidgets.QFormLayout.SpanningRole, self.title_label)
|
||||
self.install_dir_label = QtWidgets.QLabel(InstallDialog)
|
||||
self.install_dir_label.setObjectName("install_dir_label")
|
||||
self.install_dialog_layout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.install_dir_label)
|
||||
self.main_layout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.install_dir_label)
|
||||
self.platform_label = QtWidgets.QLabel(InstallDialog)
|
||||
self.platform_label.setObjectName("platform_label")
|
||||
self.install_dialog_layout.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.platform_label)
|
||||
self.main_layout.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.platform_label)
|
||||
self.platform_combo = QtWidgets.QComboBox(InstallDialog)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
|
@ -35,43 +35,54 @@ class Ui_InstallDialog(object):
|
|||
sizePolicy.setHeightForWidth(self.platform_combo.sizePolicy().hasHeightForWidth())
|
||||
self.platform_combo.setSizePolicy(sizePolicy)
|
||||
self.platform_combo.setObjectName("platform_combo")
|
||||
self.install_dialog_layout.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.platform_combo)
|
||||
self.main_layout.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.platform_combo)
|
||||
self.shortcut_label = QtWidgets.QLabel(InstallDialog)
|
||||
self.shortcut_label.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter)
|
||||
self.shortcut_label.setObjectName("shortcut_label")
|
||||
self.install_dialog_layout.setWidget(3, QtWidgets.QFormLayout.LabelRole, self.shortcut_label)
|
||||
self.main_layout.setWidget(3, QtWidgets.QFormLayout.LabelRole, self.shortcut_label)
|
||||
self.shortcut_check = QtWidgets.QCheckBox(InstallDialog)
|
||||
self.shortcut_check.setText("")
|
||||
self.shortcut_check.setObjectName("shortcut_check")
|
||||
self.install_dialog_layout.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.shortcut_check)
|
||||
self.main_layout.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.shortcut_check)
|
||||
self.selectable_layout = QtWidgets.QVBoxLayout()
|
||||
self.selectable_layout.setObjectName("selectable_layout")
|
||||
self.install_dialog_layout.setLayout(4, QtWidgets.QFormLayout.SpanningRole, self.selectable_layout)
|
||||
self.main_layout.setLayout(4, QtWidgets.QFormLayout.SpanningRole, self.selectable_layout)
|
||||
self.advanced_layout = QtWidgets.QVBoxLayout()
|
||||
self.advanced_layout.setObjectName("advanced_layout")
|
||||
self.install_dialog_layout.setLayout(5, QtWidgets.QFormLayout.SpanningRole, self.advanced_layout)
|
||||
self.main_layout.setLayout(5, QtWidgets.QFormLayout.SpanningRole, self.advanced_layout)
|
||||
self.download_size_label = QtWidgets.QLabel(InstallDialog)
|
||||
self.download_size_label.setObjectName("download_size_label")
|
||||
self.install_dialog_layout.setWidget(6, QtWidgets.QFormLayout.LabelRole, self.download_size_label)
|
||||
self.main_layout.setWidget(6, QtWidgets.QFormLayout.LabelRole, self.download_size_label)
|
||||
self.download_size_text = QtWidgets.QLabel(InstallDialog)
|
||||
font = QtGui.QFont()
|
||||
font.setItalic(True)
|
||||
self.download_size_text.setFont(font)
|
||||
self.download_size_text.setObjectName("download_size_text")
|
||||
self.install_dialog_layout.setWidget(6, QtWidgets.QFormLayout.FieldRole, self.download_size_text)
|
||||
self.main_layout.setWidget(6, QtWidgets.QFormLayout.FieldRole, self.download_size_text)
|
||||
self.install_size_label = QtWidgets.QLabel(InstallDialog)
|
||||
self.install_size_label.setObjectName("install_size_label")
|
||||
self.install_dialog_layout.setWidget(7, QtWidgets.QFormLayout.LabelRole, self.install_size_label)
|
||||
self.main_layout.setWidget(7, QtWidgets.QFormLayout.LabelRole, self.install_size_label)
|
||||
self.install_size_text = QtWidgets.QLabel(InstallDialog)
|
||||
font = QtGui.QFont()
|
||||
font.setItalic(True)
|
||||
self.install_size_text.setFont(font)
|
||||
self.install_size_text.setWordWrap(True)
|
||||
self.install_size_text.setObjectName("install_size_text")
|
||||
self.install_dialog_layout.setWidget(7, QtWidgets.QFormLayout.FieldRole, self.install_size_text)
|
||||
self.main_layout.setWidget(7, QtWidgets.QFormLayout.FieldRole, self.install_size_text)
|
||||
self.avail_space_label = QtWidgets.QLabel(InstallDialog)
|
||||
self.avail_space_label.setObjectName("avail_space_label")
|
||||
self.main_layout.setWidget(8, QtWidgets.QFormLayout.LabelRole, self.avail_space_label)
|
||||
self.avail_space = QtWidgets.QLabel(InstallDialog)
|
||||
font = QtGui.QFont()
|
||||
font.setBold(True)
|
||||
font.setWeight(75)
|
||||
self.avail_space.setFont(font)
|
||||
self.avail_space.setText("")
|
||||
self.avail_space.setObjectName("avail_space")
|
||||
self.main_layout.setWidget(8, QtWidgets.QFormLayout.FieldRole, self.avail_space)
|
||||
self.warning_label = QtWidgets.QLabel(InstallDialog)
|
||||
self.warning_label.setObjectName("warning_label")
|
||||
self.install_dialog_layout.setWidget(9, QtWidgets.QFormLayout.LabelRole, self.warning_label)
|
||||
self.main_layout.setWidget(9, QtWidgets.QFormLayout.LabelRole, self.warning_label)
|
||||
self.warning_text = QtWidgets.QLabel(InstallDialog)
|
||||
font = QtGui.QFont()
|
||||
font.setItalic(True)
|
||||
|
@ -81,57 +92,29 @@ class Ui_InstallDialog(object):
|
|||
self.warning_text.setWordWrap(True)
|
||||
self.warning_text.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByMouse|QtCore.Qt.TextSelectableByMouse)
|
||||
self.warning_text.setObjectName("warning_text")
|
||||
self.install_dialog_layout.setWidget(9, QtWidgets.QFormLayout.FieldRole, self.warning_text)
|
||||
self.button_layout = QtWidgets.QHBoxLayout()
|
||||
self.button_layout.setObjectName("button_layout")
|
||||
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
||||
self.button_layout.addItem(spacerItem)
|
||||
self.cancel_button = QtWidgets.QPushButton(InstallDialog)
|
||||
self.cancel_button.setObjectName("cancel_button")
|
||||
self.button_layout.addWidget(self.cancel_button)
|
||||
self.verify_button = QtWidgets.QPushButton(InstallDialog)
|
||||
self.verify_button.setObjectName("verify_button")
|
||||
self.button_layout.addWidget(self.verify_button)
|
||||
self.install_button = QtWidgets.QPushButton(InstallDialog)
|
||||
self.install_button.setObjectName("install_button")
|
||||
self.button_layout.addWidget(self.install_button)
|
||||
self.install_dialog_layout.setLayout(10, QtWidgets.QFormLayout.SpanningRole, self.button_layout)
|
||||
self.avail_space_lbl = QtWidgets.QLabel(InstallDialog)
|
||||
self.avail_space_lbl.setObjectName("avail_space_lbl")
|
||||
self.install_dialog_layout.setWidget(8, QtWidgets.QFormLayout.LabelRole, self.avail_space_lbl)
|
||||
self.avail_space = QtWidgets.QLabel(InstallDialog)
|
||||
font = QtGui.QFont()
|
||||
font.setBold(True)
|
||||
font.setWeight(75)
|
||||
self.avail_space.setFont(font)
|
||||
self.avail_space.setText("")
|
||||
self.avail_space.setObjectName("avail_space")
|
||||
self.install_dialog_layout.setWidget(8, QtWidgets.QFormLayout.FieldRole, self.avail_space)
|
||||
self.main_layout.setWidget(9, QtWidgets.QFormLayout.FieldRole, self.warning_text)
|
||||
|
||||
self.retranslateUi(InstallDialog)
|
||||
|
||||
def retranslateUi(self, InstallDialog):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
self.install_dialog_label.setText(_translate("InstallDialog", "error"))
|
||||
self.install_dir_label.setText(_translate("InstallDialog", "Install directory"))
|
||||
self.title_label.setText(_translate("InstallDialog", "error"))
|
||||
self.install_dir_label.setText(_translate("InstallDialog", "Install folder"))
|
||||
self.platform_label.setText(_translate("InstallDialog", "Platform"))
|
||||
self.shortcut_label.setText(_translate("InstallDialog", "Create shortcut"))
|
||||
self.download_size_label.setText(_translate("InstallDialog", "Download size"))
|
||||
self.download_size_text.setText(_translate("InstallDialog", "Click verify..."))
|
||||
self.install_size_label.setText(_translate("InstallDialog", "Total install size"))
|
||||
self.install_size_text.setText(_translate("InstallDialog", "Click verify..."))
|
||||
self.avail_space_label.setText(_translate("InstallDialog", "Available space"))
|
||||
self.warning_label.setText(_translate("InstallDialog", "Warning"))
|
||||
self.warning_text.setText(_translate("InstallDialog", "None"))
|
||||
self.cancel_button.setText(_translate("InstallDialog", "Cancel"))
|
||||
self.verify_button.setText(_translate("InstallDialog", "Verify"))
|
||||
self.install_button.setText(_translate("InstallDialog", "Install"))
|
||||
self.avail_space_lbl.setText(_translate("InstallDialog", "Available space"))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
app = QtWidgets.QApplication(sys.argv)
|
||||
InstallDialog = QtWidgets.QDialog()
|
||||
InstallDialog = QtWidgets.QWidget()
|
||||
ui = Ui_InstallDialog()
|
||||
ui.setupUi(InstallDialog)
|
||||
InstallDialog.show()
|
||||
|
|
|
@ -1,24 +1,24 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>InstallDialog</class>
|
||||
<widget class="QDialog" name="InstallDialog">
|
||||
<widget class="QWidget" name="InstallDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>272</width>
|
||||
<height>238</height>
|
||||
<width>179</width>
|
||||
<height>204</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">InstallDialog</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="install_dialog_layout">
|
||||
<layout class="QFormLayout" name="main_layout">
|
||||
<property name="labelAlignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QLabel" name="install_dialog_label">
|
||||
<widget class="QLabel" name="title_label">
|
||||
<property name="text">
|
||||
<string>error</string>
|
||||
</property>
|
||||
|
@ -27,7 +27,7 @@
|
|||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="install_dir_label">
|
||||
<property name="text">
|
||||
<string>Install directory</string>
|
||||
<string>Install folder</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -112,6 +112,26 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="avail_space_label">
|
||||
<property name="text">
|
||||
<string>Available space</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<widget class="QLabel" name="avail_space">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<widget class="QLabel" name="warning_label">
|
||||
<property name="text">
|
||||
|
@ -143,64 +163,6 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="0" colspan="2">
|
||||
<layout class="QHBoxLayout" name="button_layout">
|
||||
<item>
|
||||
<spacer name="button_hspacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="cancel_button">
|
||||
<property name="text">
|
||||
<string>Cancel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="verify_button">
|
||||
<property name="text">
|
||||
<string>Verify</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="install_button">
|
||||
<property name="text">
|
||||
<string>Install</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="avail_space_lbl">
|
||||
<property name="text">
|
||||
<string>Available space</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<widget class="QLabel" name="avail_space">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
|
|
|
@ -1,56 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'rare/ui/components/dialogs/sync_save_dialog.ui'
|
||||
#
|
||||
# Created by: PyQt5 UI code generator 5.15.7
|
||||
#
|
||||
# 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.
|
||||
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
|
||||
class Ui_SyncSaveDialog(object):
|
||||
def setupUi(self, SyncSaveDialog):
|
||||
SyncSaveDialog.setObjectName("SyncSaveDialog")
|
||||
SyncSaveDialog.resize(648, 394)
|
||||
self.verticalLayout = QtWidgets.QVBoxLayout(SyncSaveDialog)
|
||||
self.verticalLayout.setObjectName("verticalLayout")
|
||||
self.title_label = QtWidgets.QLabel(SyncSaveDialog)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Maximum)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.title_label.sizePolicy().hasHeightForWidth())
|
||||
self.title_label.setSizePolicy(sizePolicy)
|
||||
self.title_label.setObjectName("title_label")
|
||||
self.verticalLayout.addWidget(self.title_label)
|
||||
self.sync_widget_layout = QtWidgets.QHBoxLayout()
|
||||
self.sync_widget_layout.setObjectName("sync_widget_layout")
|
||||
self.verticalLayout.addLayout(self.sync_widget_layout)
|
||||
self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
|
||||
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
|
||||
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
||||
self.horizontalLayout_2.addItem(spacerItem)
|
||||
self.cancel_button = QtWidgets.QPushButton(SyncSaveDialog)
|
||||
self.cancel_button.setObjectName("cancel_button")
|
||||
self.horizontalLayout_2.addWidget(self.cancel_button)
|
||||
self.verticalLayout.addLayout(self.horizontalLayout_2)
|
||||
|
||||
self.retranslateUi(SyncSaveDialog)
|
||||
|
||||
def retranslateUi(self, SyncSaveDialog):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
SyncSaveDialog.setWindowTitle(_translate("SyncSaveDialog", "Sync saves with cloud"))
|
||||
self.title_label.setText(_translate("SyncSaveDialog", "Select save, you want to use for "))
|
||||
self.cancel_button.setText(_translate("SyncSaveDialog", "Cancel"))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
app = QtWidgets.QApplication(sys.argv)
|
||||
SyncSaveDialog = QtWidgets.QDialog()
|
||||
ui = Ui_SyncSaveDialog()
|
||||
ui.setupUi(SyncSaveDialog)
|
||||
SyncSaveDialog.show()
|
||||
sys.exit(app.exec_())
|
|
@ -1,61 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>SyncSaveDialog</class>
|
||||
<widget class="QDialog" name="SyncSaveDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>648</width>
|
||||
<height>394</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Sync saves with cloud</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="title_label">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Select save, you want to use for </string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="sync_widget_layout"/>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="cancel_button">
|
||||
<property name="text">
|
||||
<string>Cancel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -0,0 +1,52 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'rare/ui/components/tabs/games/game_info/cloud_settings_widget.ui'
|
||||
#
|
||||
# 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.
|
||||
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
|
||||
class Ui_CloudSettingsWidget(object):
|
||||
def setupUi(self, CloudSettingsWidget):
|
||||
CloudSettingsWidget.setObjectName("CloudSettingsWidget")
|
||||
CloudSettingsWidget.resize(388, 78)
|
||||
CloudSettingsWidget.setWindowTitle("CloudSettingsWidget")
|
||||
self.main_layout = QtWidgets.QFormLayout(CloudSettingsWidget)
|
||||
self.main_layout.setLabelAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||
self.main_layout.setObjectName("main_layout")
|
||||
self.sync_label = QtWidgets.QLabel(CloudSettingsWidget)
|
||||
self.sync_label.setObjectName("sync_label")
|
||||
self.main_layout.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.sync_label)
|
||||
self.sync_check = QtWidgets.QCheckBox(CloudSettingsWidget)
|
||||
font = QtGui.QFont()
|
||||
font.setItalic(True)
|
||||
self.sync_check.setFont(font)
|
||||
self.sync_check.setText("Automatically synchronize saves with the cloud")
|
||||
self.sync_check.setObjectName("sync_check")
|
||||
self.main_layout.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.sync_check)
|
||||
self.path_label = QtWidgets.QLabel(CloudSettingsWidget)
|
||||
self.path_label.setObjectName("path_label")
|
||||
self.main_layout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.path_label)
|
||||
|
||||
self.retranslateUi(CloudSettingsWidget)
|
||||
|
||||
def retranslateUi(self, CloudSettingsWidget):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
CloudSettingsWidget.setTitle(_translate("CloudSettingsWidget", "Settings"))
|
||||
self.sync_label.setText(_translate("CloudSettingsWidget", "Enable sync"))
|
||||
self.path_label.setText(_translate("CloudSettingsWidget", "Saves path"))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
app = QtWidgets.QApplication(sys.argv)
|
||||
CloudSettingsWidget = QtWidgets.QGroupBox()
|
||||
ui = Ui_CloudSettingsWidget()
|
||||
ui.setupUi(CloudSettingsWidget)
|
||||
CloudSettingsWidget.show()
|
||||
sys.exit(app.exec_())
|
|
@ -0,0 +1,53 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>CloudSettingsWidget</class>
|
||||
<widget class="QGroupBox" name="CloudSettingsWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>388</width>
|
||||
<height>78</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">CloudSettingsWidget</string>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Settings</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="main_layout">
|
||||
<property name="labelAlignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="sync_label">
|
||||
<property name="text">
|
||||
<string>Enable sync</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="sync_check">
|
||||
<property name="font">
|
||||
<font>
|
||||
<italic>true</italic>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">Automatically synchronize saves with the cloud</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="path_label">
|
||||
<property name="text">
|
||||
<string>Saves path</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -1,8 +1,8 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'rare/ui/components/tabs/games/game_info/sync_widget.ui'
|
||||
# Form implementation generated from reading ui file 'rare/ui/components/tabs/games/game_info/cloud_sync_widget.ui'
|
||||
#
|
||||
# Created by: PyQt5 UI code generator 5.15.9
|
||||
# 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.
|
||||
|
@ -11,29 +11,29 @@
|
|||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
|
||||
class Ui_SyncWidget(object):
|
||||
def setupUi(self, SyncWidget):
|
||||
SyncWidget.setObjectName("SyncWidget")
|
||||
SyncWidget.resize(438, 137)
|
||||
class Ui_CloudSyncWidget(object):
|
||||
def setupUi(self, CloudSyncWidget):
|
||||
CloudSyncWidget.setObjectName("CloudSyncWidget")
|
||||
CloudSyncWidget.resize(438, 137)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(SyncWidget.sizePolicy().hasHeightForWidth())
|
||||
SyncWidget.setSizePolicy(sizePolicy)
|
||||
SyncWidget.setWindowTitle("SyncWidget")
|
||||
self.sync_layout = QtWidgets.QHBoxLayout(SyncWidget)
|
||||
self.sync_layout.setContentsMargins(0, 0, 0, 0)
|
||||
self.sync_layout.setObjectName("sync_layout")
|
||||
self.local_gb = QtWidgets.QGroupBox(SyncWidget)
|
||||
self.local_gb.setObjectName("local_gb")
|
||||
self.local_layout = QtWidgets.QVBoxLayout(self.local_gb)
|
||||
sizePolicy.setHeightForWidth(CloudSyncWidget.sizePolicy().hasHeightForWidth())
|
||||
CloudSyncWidget.setSizePolicy(sizePolicy)
|
||||
CloudSyncWidget.setWindowTitle("SyncWidget")
|
||||
self.main_layout = QtWidgets.QHBoxLayout(CloudSyncWidget)
|
||||
self.main_layout.setContentsMargins(0, 0, 0, 0)
|
||||
self.main_layout.setObjectName("main_layout")
|
||||
self.local_group = QtWidgets.QGroupBox(CloudSyncWidget)
|
||||
self.local_group.setObjectName("local_group")
|
||||
self.local_layout = QtWidgets.QVBoxLayout(self.local_group)
|
||||
self.local_layout.setObjectName("local_layout")
|
||||
self.date_info_local = QtWidgets.QLabel(self.local_gb)
|
||||
self.date_info_local = QtWidgets.QLabel(self.local_group)
|
||||
self.date_info_local.setText("")
|
||||
self.date_info_local.setAlignment(QtCore.Qt.AlignCenter)
|
||||
self.date_info_local.setObjectName("date_info_local")
|
||||
self.local_layout.addWidget(self.date_info_local)
|
||||
self.icon_local = QtWidgets.QLabel(self.local_gb)
|
||||
self.icon_local = QtWidgets.QLabel(self.local_group)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
|
@ -43,26 +43,26 @@ class Ui_SyncWidget(object):
|
|||
self.icon_local.setAlignment(QtCore.Qt.AlignCenter)
|
||||
self.icon_local.setObjectName("icon_local")
|
||||
self.local_layout.addWidget(self.icon_local)
|
||||
self.age_label_local = QtWidgets.QLabel(self.local_gb)
|
||||
self.age_label_local = QtWidgets.QLabel(self.local_group)
|
||||
self.age_label_local.setText("")
|
||||
self.age_label_local.setAlignment(QtCore.Qt.AlignCenter)
|
||||
self.age_label_local.setObjectName("age_label_local")
|
||||
self.local_layout.addWidget(self.age_label_local)
|
||||
self.upload_button = QtWidgets.QPushButton(self.local_gb)
|
||||
self.upload_button = QtWidgets.QPushButton(self.local_group)
|
||||
self.upload_button.setMinimumSize(QtCore.QSize(192, 0))
|
||||
self.upload_button.setObjectName("upload_button")
|
||||
self.local_layout.addWidget(self.upload_button)
|
||||
self.sync_layout.addWidget(self.local_gb)
|
||||
self.cloud_gb = QtWidgets.QGroupBox(SyncWidget)
|
||||
self.cloud_gb.setObjectName("cloud_gb")
|
||||
self.cloud_layout = QtWidgets.QVBoxLayout(self.cloud_gb)
|
||||
self.main_layout.addWidget(self.local_group)
|
||||
self.cloud_group = QtWidgets.QGroupBox(CloudSyncWidget)
|
||||
self.cloud_group.setObjectName("cloud_group")
|
||||
self.cloud_layout = QtWidgets.QVBoxLayout(self.cloud_group)
|
||||
self.cloud_layout.setObjectName("cloud_layout")
|
||||
self.date_info_remote = QtWidgets.QLabel(self.cloud_gb)
|
||||
self.date_info_remote = QtWidgets.QLabel(self.cloud_group)
|
||||
self.date_info_remote.setText("")
|
||||
self.date_info_remote.setAlignment(QtCore.Qt.AlignCenter)
|
||||
self.date_info_remote.setObjectName("date_info_remote")
|
||||
self.cloud_layout.addWidget(self.date_info_remote)
|
||||
self.icon_remote = QtWidgets.QLabel(self.cloud_gb)
|
||||
self.icon_remote = QtWidgets.QLabel(self.cloud_group)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
|
@ -72,32 +72,32 @@ class Ui_SyncWidget(object):
|
|||
self.icon_remote.setAlignment(QtCore.Qt.AlignCenter)
|
||||
self.icon_remote.setObjectName("icon_remote")
|
||||
self.cloud_layout.addWidget(self.icon_remote)
|
||||
self.age_label_remote = QtWidgets.QLabel(self.cloud_gb)
|
||||
self.age_label_remote = QtWidgets.QLabel(self.cloud_group)
|
||||
self.age_label_remote.setText("")
|
||||
self.age_label_remote.setAlignment(QtCore.Qt.AlignCenter)
|
||||
self.age_label_remote.setObjectName("age_label_remote")
|
||||
self.cloud_layout.addWidget(self.age_label_remote)
|
||||
self.download_button = QtWidgets.QPushButton(self.cloud_gb)
|
||||
self.download_button = QtWidgets.QPushButton(self.cloud_group)
|
||||
self.download_button.setMinimumSize(QtCore.QSize(192, 0))
|
||||
self.download_button.setObjectName("download_button")
|
||||
self.cloud_layout.addWidget(self.download_button)
|
||||
self.sync_layout.addWidget(self.cloud_gb)
|
||||
self.main_layout.addWidget(self.cloud_group)
|
||||
|
||||
self.retranslateUi(SyncWidget)
|
||||
self.retranslateUi(CloudSyncWidget)
|
||||
|
||||
def retranslateUi(self, SyncWidget):
|
||||
def retranslateUi(self, CloudSyncWidget):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
self.local_gb.setTitle(_translate("SyncWidget", "Local"))
|
||||
self.upload_button.setText(_translate("SyncWidget", "Upload"))
|
||||
self.cloud_gb.setTitle(_translate("SyncWidget", "Cloud"))
|
||||
self.download_button.setText(_translate("SyncWidget", "Download"))
|
||||
self.local_group.setTitle(_translate("CloudSyncWidget", "Local"))
|
||||
self.upload_button.setText(_translate("CloudSyncWidget", "Upload"))
|
||||
self.cloud_group.setTitle(_translate("CloudSyncWidget", "Cloud"))
|
||||
self.download_button.setText(_translate("CloudSyncWidget", "Download"))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
app = QtWidgets.QApplication(sys.argv)
|
||||
SyncWidget = QtWidgets.QWidget()
|
||||
ui = Ui_SyncWidget()
|
||||
ui.setupUi(SyncWidget)
|
||||
SyncWidget.show()
|
||||
CloudSyncWidget = QtWidgets.QWidget()
|
||||
ui = Ui_CloudSyncWidget()
|
||||
ui.setupUi(CloudSyncWidget)
|
||||
CloudSyncWidget.show()
|
||||
sys.exit(app.exec_())
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>SyncWidget</class>
|
||||
<widget class="QWidget" name="SyncWidget">
|
||||
<class>CloudSyncWidget</class>
|
||||
<widget class="QWidget" name="CloudSyncWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
|
@ -19,7 +19,7 @@
|
|||
<property name="windowTitle">
|
||||
<string notr="true">SyncWidget</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="sync_layout">
|
||||
<layout class="QHBoxLayout" name="main_layout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
|
@ -33,7 +33,7 @@
|
|||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="local_gb">
|
||||
<widget class="QGroupBox" name="local_group">
|
||||
<property name="title">
|
||||
<string>Local</string>
|
||||
</property>
|
||||
|
@ -91,7 +91,7 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="cloud_gb">
|
||||
<widget class="QGroupBox" name="cloud_group">
|
||||
<property name="title">
|
||||
<string>Cloud</string>
|
||||
</property>
|
|
@ -1,44 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'rare/ui/components/tabs/games/game_info/cloud_widget.ui'
|
||||
#
|
||||
# Created by: PyQt5 UI code generator 5.15.7
|
||||
#
|
||||
# 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.
|
||||
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
|
||||
class Ui_CloudWidget(object):
|
||||
def setupUi(self, CloudWidget):
|
||||
CloudWidget.setObjectName("CloudWidget")
|
||||
CloudWidget.resize(251, 93)
|
||||
CloudWidget.setWindowTitle("GroupBox")
|
||||
self.cloud_layout = QtWidgets.QFormLayout(CloudWidget)
|
||||
self.cloud_layout.setObjectName("cloud_layout")
|
||||
self.cloud_sync_label = QtWidgets.QLabel(CloudWidget)
|
||||
self.cloud_sync_label.setObjectName("cloud_sync_label")
|
||||
self.cloud_layout.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.cloud_sync_label)
|
||||
self.cloud_sync = QtWidgets.QCheckBox(CloudWidget)
|
||||
self.cloud_sync.setText("")
|
||||
self.cloud_sync.setObjectName("cloud_sync")
|
||||
self.cloud_layout.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.cloud_sync)
|
||||
|
||||
self.retranslateUi(CloudWidget)
|
||||
|
||||
def retranslateUi(self, CloudWidget):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
CloudWidget.setTitle(_translate("CloudWidget", "Options"))
|
||||
self.cloud_sync_label.setText(_translate("CloudWidget", "Sync with cloud"))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
app = QtWidgets.QApplication(sys.argv)
|
||||
CloudWidget = QtWidgets.QGroupBox()
|
||||
ui = Ui_CloudWidget()
|
||||
ui.setupUi(CloudWidget)
|
||||
CloudWidget.show()
|
||||
sys.exit(app.exec_())
|
|
@ -1,38 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>CloudWidget</class>
|
||||
<widget class="QGroupBox" name="CloudWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>251</width>
|
||||
<height>93</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">GroupBox</string>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Options</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="cloud_layout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="cloud_sync_label">
|
||||
<property name="text">
|
||||
<string>Sync with cloud</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QCheckBox" name="cloud_sync">
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
# Form implementation generated from reading ui file 'rare/ui/components/tabs/games/game_info/game_info.ui'
|
||||
#
|
||||
# Created by: PyQt5 UI code generator 5.15.9
|
||||
# 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.
|
||||
|
@ -336,13 +336,13 @@ class Ui_GameInfo(object):
|
|||
self.lbl_install_path.setText(_translate("GameInfo", "Installation Path"))
|
||||
self.lbl_platform.setText(_translate("GameInfo", "Platform"))
|
||||
self.lbl_game_actions.setText(_translate("GameInfo", "Actions"))
|
||||
self.modify_button.setText(_translate("GameInfo", "Modify Installation"))
|
||||
self.verify_button.setText(_translate("GameInfo", "Verify Installation"))
|
||||
self.repair_button.setText(_translate("GameInfo", "Repair Installation"))
|
||||
self.move_button.setText(_translate("GameInfo", "Move Installation"))
|
||||
self.uninstall_button.setText(_translate("GameInfo", "Uninstall Game"))
|
||||
self.install_button.setText(_translate("GameInfo", "Install Game"))
|
||||
self.import_button.setText(_translate("GameInfo", "Import Game"))
|
||||
self.modify_button.setText(_translate("GameInfo", "Modify"))
|
||||
self.verify_button.setText(_translate("GameInfo", "Verify"))
|
||||
self.repair_button.setText(_translate("GameInfo", "Repair"))
|
||||
self.move_button.setText(_translate("GameInfo", "Move"))
|
||||
self.uninstall_button.setText(_translate("GameInfo", "Uninstall"))
|
||||
self.install_button.setText(_translate("GameInfo", "Install"))
|
||||
self.import_button.setText(_translate("GameInfo", "Import"))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
@ -395,7 +395,7 @@
|
|||
<item>
|
||||
<widget class="QPushButton" name="modify_button">
|
||||
<property name="text">
|
||||
<string>Modify Installation</string>
|
||||
<string>Modify</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -424,7 +424,7 @@
|
|||
<item>
|
||||
<widget class="QPushButton" name="verify_button">
|
||||
<property name="text">
|
||||
<string>Verify Installation</string>
|
||||
<string>Verify</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -461,7 +461,7 @@
|
|||
<item>
|
||||
<widget class="QPushButton" name="repair_button">
|
||||
<property name="text">
|
||||
<string>Repair Installation</string>
|
||||
<string>Repair</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -496,7 +496,7 @@
|
|||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Move Installation</string>
|
||||
<string>Move</string>
|
||||
</property>
|
||||
<property name="popupMode">
|
||||
<enum>QToolButton::InstantPopup</enum>
|
||||
|
@ -542,7 +542,7 @@
|
|||
<item>
|
||||
<widget class="QPushButton" name="uninstall_button">
|
||||
<property name="text">
|
||||
<string>Uninstall Game</string>
|
||||
<string>Uninstall</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -565,14 +565,14 @@
|
|||
<item>
|
||||
<widget class="QPushButton" name="install_button">
|
||||
<property name="text">
|
||||
<string>Install Game</string>
|
||||
<string>Install</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="import_button">
|
||||
<property name="text">
|
||||
<string>Import Game</string>
|
||||
<string>Import</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
|
@ -141,7 +141,7 @@ def get_rare_executable() -> List[str]:
|
|||
executable = [sys.executable]
|
||||
elif sys.argv[0].endswith("__main__.py"):
|
||||
executable = [sys.executable, "-m", "rare"]
|
||||
elif platform.system() == "Linux" or platform.system() == "Darwin" or platform.system() == "FreeBSD":
|
||||
elif platform.system() in {"Linux", "FreeBSD", "Darwin"}:
|
||||
if p := os.environ.get("APPIMAGE"):
|
||||
executable = [p]
|
||||
else:
|
||||
|
@ -214,7 +214,7 @@ def create_desktop_link(app_name: str, app_title: str = "", link_name: str = "",
|
|||
else:
|
||||
logger.info(f"Creating shortcut for {app_title} at {shortcut_path}")
|
||||
|
||||
if platform.system() == "Linux" or platform.system() == "FreeBSD":
|
||||
if platform.system() in {"Linux", "FreeBSD"}:
|
||||
executable = get_rare_executable()
|
||||
executable = shlex.join(executable)
|
||||
if not for_rare:
|
||||
|
|
|
@ -39,11 +39,11 @@ class RareAppException(QObject):
|
|||
self.logger.fatal(message)
|
||||
action = QMessageBox.warning(
|
||||
None, exc_type.__name__, message,
|
||||
buttons=QMessageBox.Ignore | QMessageBox.Close,
|
||||
defaultButton=QMessageBox.Ignore
|
||||
buttons=QMessageBox.Ignore | QMessageBox.Abort,
|
||||
defaultButton=QMessageBox.Abort
|
||||
)
|
||||
if action == QMessageBox.RejectRole:
|
||||
QApplication.exit(1)
|
||||
if action == QMessageBox.Abort:
|
||||
QApplication.quit()
|
||||
|
||||
|
||||
class RareApp(QApplication):
|
||||
|
@ -85,13 +85,6 @@ class RareApp(QApplication):
|
|||
logging.getLogger("requests").setLevel(logging.WARNING)
|
||||
logging.getLogger("urllib3").setLevel(logging.WARNING)
|
||||
logging.getLogger("asyncio").setLevel(logging.WARNING)
|
||||
self.logger.info(
|
||||
f"Launching Rare version {rare.__version__} Codename: {rare.__codename__}\n"
|
||||
f" - Using Legendary {legendary.__version__} Codename: {legendary.__codename__} as backend\n"
|
||||
f" - Operating System: {platform.system()}, Python version: {platform.python_version()}\n"
|
||||
f" - Running {sys.executable} {' '.join(sys.argv)}\n"
|
||||
f" - Qt version: {QT_VERSION_STR}, PyQt version: {PYQT_VERSION_STR}"
|
||||
)
|
||||
else:
|
||||
logging.basicConfig(
|
||||
format="[%(name)s] %(levelname)s: %(message)s",
|
||||
|
@ -100,8 +93,13 @@ class RareApp(QApplication):
|
|||
)
|
||||
file_handler.setLevel(logging.DEBUG)
|
||||
logging.root.addHandler(file_handler)
|
||||
self.logger.info(f"Launching Rare version {rare.__version__}")
|
||||
self.logger.info(f"Operating System: {platform.system()}")
|
||||
self.logger.info(
|
||||
f"Launching Rare version {rare.__version__} Codename: {rare.__codename__}\n"
|
||||
f" - Using Legendary {legendary.__version__} Codename: {legendary.__codename__} as backend\n"
|
||||
f" - Operating System: {platform.system()}, Python version: {platform.python_version()}\n"
|
||||
f" - Running {sys.executable} {' '.join(sys.argv)}\n"
|
||||
f" - Qt version: {QT_VERSION_STR}, PyQt version: {PYQT_VERSION_STR}"
|
||||
)
|
||||
|
||||
self.settings = QSettings()
|
||||
|
||||
|
|
|
@ -2,8 +2,10 @@ requests
|
|||
PyQt5
|
||||
QtAwesome
|
||||
setuptools
|
||||
legendary-gl>=0.20.33
|
||||
legendary-gl>=0.20.34; platform_system != "Windows" or platform_system != "Darwin"
|
||||
legendary-gl @ git+https://github.com/derrod/legendary@96e07ff ; platform_system == "Windows" or platform_system == "Darwin"
|
||||
orjson
|
||||
vdf; platform_system != "Windows"
|
||||
pywin32; platform_system == "Windows"
|
||||
pywebview[qt]; platform_system == "Linux"
|
||||
pywebview[qt]; platform_system == "FreeBSD"
|
||||
|
|
|
@ -2,7 +2,8 @@ requests
|
|||
PyQt5
|
||||
QtAwesome
|
||||
setuptools
|
||||
legendary-gl>=0.20.34
|
||||
legendary-gl>=0.20.34; platform_system != "Windows" or platform_system != "Darwin"
|
||||
legendary-gl @ git+https://github.com/derrod/legendary@96e07ff ; platform_system == "Windows" or platform_system == "Darwin"
|
||||
orjson
|
||||
vdf; platform_system != "Windows"
|
||||
pywin32; platform_system == "Windows"
|
||||
|
|
Loading…
Reference in a new issue