Rebasing cloud_save_update with main
This commit is contained in:
parent
9f638ce16c
commit
8b8c3a1f64
|
@ -105,7 +105,8 @@ class LaunchDialog(QDialog, Ui_LaunchDialog):
|
|||
["32bit", self.core.get_game_and_dlc_list, (True, "Win32")],
|
||||
["mac", self.core.get_game_and_dlc_list, (True, "Mac")],
|
||||
["assets", self.core.egs.get_game_assets, ()],
|
||||
["no_assets", self.core.get_non_asset_library_items, ()]
|
||||
["no_assets", self.core.get_non_asset_library_items, ()],
|
||||
["saves", self.core.get_save_games, ()]
|
||||
]
|
||||
for r in api_requests:
|
||||
worker = ApiRequestWorker(*r)
|
||||
|
@ -138,6 +139,9 @@ class LaunchDialog(QDialog, Ui_LaunchDialog):
|
|||
elif text == "no_assets":
|
||||
self.api_results.no_asset_games = result[0] if result else []
|
||||
|
||||
elif text == "saves":
|
||||
self.api_results.saves = result
|
||||
|
||||
if self.api_results:
|
||||
self.finish()
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ class MainWindow(QMainWindow):
|
|||
if shared.args.subparser == "launch":
|
||||
if shared.args.app_name in [i.app_name for i in self.tab_widget.games_tab.installed]:
|
||||
logger.info("Launching " + self.core.get_installed_game(shared.args.app_name).title)
|
||||
self.tab_widget.games_tab.widgets[shared.args.app_name][1].launch()
|
||||
self.tab_widget.games_tab.widgets[shared.args.app_name][1].prepare_launch()
|
||||
else:
|
||||
logger.info(
|
||||
f"Could not find {shared.args.app_name} in Games or it is not installed")
|
||||
|
@ -56,8 +56,8 @@ class MainWindow(QMainWindow):
|
|||
file.close()
|
||||
if action.startswith("launch"):
|
||||
game = action.replace("launch ", "").replace("\n", "")
|
||||
if self.core.is_installed(game):
|
||||
self.tab_widget.games_tab.widgets[game][1].launch()
|
||||
if game in [i.app_name for i in self.tab_widget.games_tab.game_list] and self.core.is_installed(game):
|
||||
self.tab_widget.games_tab.game_utils.prepare_launch(game, offline=shared.args.offline)
|
||||
else:
|
||||
logger.info(f"Could not find {game} in Games")
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ from PyQt5.QtGui import QImage, QPixmap
|
|||
from PyQt5.QtWidgets import QStackedWidget, QVBoxLayout, QWidget
|
||||
|
||||
import rare.shared as shared
|
||||
from .cloud_save_utils import CloudSaveUtils
|
||||
from legendary.models.game import Game, InstalledGame
|
||||
from rare.components.dialogs.uninstall_dialog import UninstallDialog
|
||||
from rare.ui.components.tabs.games.games_tab import Ui_GamesTab
|
||||
|
@ -38,6 +39,9 @@ class GamesTab(QStackedWidget, Ui_GamesTab):
|
|||
self.core = shared.core
|
||||
self.signals = shared.signals
|
||||
self.settings = QSettings()
|
||||
self.cloud_save_utils = CloudSaveUtils()
|
||||
self.cloud_save_utils.sync_finished.connect(self.sync_finished)
|
||||
self.before_launch_sync = dict()
|
||||
|
||||
self.game_list = shared.api_results.game_list
|
||||
self.dlcs = shared.api_results.dlcs
|
||||
|
@ -129,7 +133,7 @@ class GamesTab(QStackedWidget, Ui_GamesTab):
|
|||
self.import_sync_tabs.show_egl_sync()
|
||||
|
||||
def show_game_info(self, game):
|
||||
self.game_info_tabs.update_game(game, self.dlcs)
|
||||
self.game_info_tabs.update_game(game)
|
||||
self.setCurrentIndex(1)
|
||||
|
||||
def show_uninstalled_info(self, game):
|
||||
|
@ -137,7 +141,6 @@ class GamesTab(QStackedWidget, Ui_GamesTab):
|
|||
self.setCurrentIndex(3)
|
||||
|
||||
def setup_game_list(self):
|
||||
|
||||
self.icon_view = QWidget()
|
||||
self.icon_view.setLayout(FlowLayout())
|
||||
self.list_view = QWidget()
|
||||
|
@ -153,12 +156,12 @@ class GamesTab(QStackedWidget, Ui_GamesTab):
|
|||
|
||||
# add installed games
|
||||
for igame in self.installed:
|
||||
icon_widget, list_widget = self.add_installed_widget(self.core.get_game(igame.app_name, update_meta=False))
|
||||
icon_widget, list_widget = self.add_installed_widget(igame.app_name)
|
||||
self.icon_view.layout().addWidget(icon_widget)
|
||||
self.list_view.layout().addWidget(list_widget)
|
||||
|
||||
for game in self.no_assets:
|
||||
icon_widget, list_widget = self.add_installed_widget(game, is_origin=True)
|
||||
icon_widget, list_widget = self.add_installed_widget(game.app_name)
|
||||
self.icon_view.layout().addWidget(icon_widget)
|
||||
self.list_view.layout().addWidget(list_widget)
|
||||
|
||||
|
@ -175,35 +178,44 @@ class GamesTab(QStackedWidget, Ui_GamesTab):
|
|||
len(self.core.get_installed_list()),
|
||||
len(self.game_list)))
|
||||
|
||||
def add_installed_widget(self, game, is_origin=False):
|
||||
pixmap = get_pixmap(game.app_name)
|
||||
def sync_finished(self, app_name):
|
||||
self.widgets[app_name][0].info_text = ""
|
||||
self.widgets[app_name][0].info_label.setText("")
|
||||
self.widgets[app_name][1].info_label.setText("")
|
||||
|
||||
if app_name in self.before_launch_sync.keys():
|
||||
self.launch(*self.before_launch_sync[app_name])
|
||||
self.before_launch_sync.pop(app_name)
|
||||
|
||||
def add_installed_widget(self, app_name):
|
||||
pixmap = get_pixmap(app_name)
|
||||
if pixmap.isNull():
|
||||
logger.info(game.app_title + " has a corrupt image.")
|
||||
download_image(self.core.get_game(game.app_name), force=True)
|
||||
pixmap = get_pixmap(game.app_name)
|
||||
logger.info(app_name + " has a corrupt image.")
|
||||
download_image(self.core.get_game(app_name), force=True)
|
||||
pixmap = get_pixmap(app_name)
|
||||
|
||||
if game.app_name in self.no_asset_names:
|
||||
igame = None
|
||||
else:
|
||||
igame = self.core.get_installed_game(game.app_name)
|
||||
icon_widget = InstalledIconWidget(app_name, pixmap)
|
||||
|
||||
icon_widget = InstalledIconWidget(igame, pixmap, is_origin, game)
|
||||
list_widget = InstalledListWidget(app_name, pixmap)
|
||||
|
||||
list_widget = InstalledListWidget(igame, pixmap, is_origin, game)
|
||||
|
||||
self.widgets[game.app_name] = (icon_widget, list_widget)
|
||||
self.widgets[app_name] = (icon_widget, list_widget)
|
||||
|
||||
icon_widget.show_info.connect(self.show_game_info)
|
||||
list_widget.show_info.connect(self.show_game_info)
|
||||
|
||||
icon_widget.launch_signal.connect(self.launch)
|
||||
icon_widget.launch_signal.connect(self.prepare_launch)
|
||||
icon_widget.finish_signal.connect(self.finished)
|
||||
|
||||
list_widget.launch_signal.connect(self.launch)
|
||||
list_widget.launch_signal.connect(self.prepare_launch)
|
||||
list_widget.finish_signal.connect(self.finished)
|
||||
|
||||
game = self.core.get_game(app_name)
|
||||
if game.supports_cloud_saves:
|
||||
icon_widget.sync_game.connect(self.cloud_save_utils.sync_before_launch_game)
|
||||
list_widget.sync_game.connect(self.cloud_save_utils.sync_before_launch_game)
|
||||
|
||||
if icon_widget.update_available:
|
||||
self.updates.add(igame.app_name)
|
||||
self.updates.add(app_name)
|
||||
|
||||
return icon_widget, list_widget
|
||||
|
||||
|
@ -230,33 +242,6 @@ class GamesTab(QStackedWidget, Ui_GamesTab):
|
|||
|
||||
return icon_widget, list_widget
|
||||
|
||||
def finished(self, app_name):
|
||||
self.running_games.remove(app_name)
|
||||
self.widgets[app_name][0].info_text = ""
|
||||
self.widgets[app_name][0].info_label.setText("")
|
||||
self.widgets[app_name][1].launch_button.setDisabled(False)
|
||||
self.widgets[app_name][1].launch_button.setText(self.tr("Launch"))
|
||||
if self.widgets[app_name][0].game.supports_cloud_saves:
|
||||
if not self.settings.value(f"{app_name}/auto_sync_cloud", True, bool) \
|
||||
and not self.settings.value("auto_sync_cloud", True, bool):
|
||||
logger.info("Auto saves disabled")
|
||||
return
|
||||
|
||||
self.widgets[app_name][0].info_text = self.tr("Sync CLoud saves")
|
||||
self.widgets[app_name][0].info_label.setText(self.tr("Sync CLoud saves"))
|
||||
self.widgets[app_name][1].info_label.setText(self.tr("Sync CLoud saves"))
|
||||
self.signals.set_discord_rpc.emit(None)
|
||||
|
||||
def launch(self, app_name):
|
||||
self.running_games.append(app_name)
|
||||
# self.game_started.emit(app_name)
|
||||
self.widgets[app_name][0].info_text = self.tr("Game running")
|
||||
self.widgets[app_name][0].info_label.setText(self.tr("Game running"))
|
||||
self.widgets[app_name][1].launch_button.setDisabled(True)
|
||||
self.widgets[app_name][1].launch_button.setText(self.tr("Game running"))
|
||||
|
||||
self.signals.set_discord_rpc.emit(app_name)
|
||||
|
||||
def filter_games(self, filter_name="all", search_text: str = ""):
|
||||
if not search_text and (t := self.head_bar.search_bar.text()):
|
||||
search_text = t
|
||||
|
@ -315,7 +300,7 @@ class GamesTab(QStackedWidget, Ui_GamesTab):
|
|||
self.widgets[app_name][1].deleteLater()
|
||||
self.widgets.pop(app_name)
|
||||
|
||||
self.add_installed_widget(self.core.get_game(app_name))
|
||||
self.add_installed_widget(app_name)
|
||||
update_list = True
|
||||
|
||||
# uninstalled
|
||||
|
@ -330,6 +315,7 @@ class GamesTab(QStackedWidget, Ui_GamesTab):
|
|||
game = self.core.get_game(app_name, False)
|
||||
self.add_uninstalled_widget(game)
|
||||
update_list = True
|
||||
|
||||
# do not update, if only update finished
|
||||
if update_list:
|
||||
self._update_games()
|
||||
|
@ -356,7 +342,7 @@ class GamesTab(QStackedWidget, Ui_GamesTab):
|
|||
self.widgets.pop(name)
|
||||
|
||||
igame = self.core.get_installed_game(name)
|
||||
self.add_installed_widget(self.core.get_game(igame.app_name))
|
||||
self.add_installed_widget(igame.app_name)
|
||||
|
||||
for name in new_uninstalled_games:
|
||||
self.icon_view.layout().removeWidget(self.widgets[name][0])
|
||||
|
|
208
rare/components/tabs/games/cloud_save_utils.py
Normal file
208
rare/components/tabs/games/cloud_save_utils.py
Normal file
|
@ -0,0 +1,208 @@
|
|||
import datetime
|
||||
from dataclasses import dataclass
|
||||
from logging import getLogger
|
||||
from typing import Union
|
||||
|
||||
from PyQt5.QtCore import QObject, pyqtSignal, QRunnable, QThreadPool, Qt
|
||||
from PyQt5.QtWidgets import QDialog, QMessageBox, QSizePolicy, QLayout
|
||||
from qtawesome import icon
|
||||
|
||||
from legendary.models.game import SaveGameStatus, InstalledGame, SaveGameFile
|
||||
from rare import shared
|
||||
from rare.ui.components.dialogs.sync_save_dialog import Ui_SyncSaveDialog
|
||||
|
||||
logger = getLogger("Cloud Saves")
|
||||
|
||||
|
||||
@dataclass
|
||||
class UploadModel:
|
||||
app_name: str
|
||||
date_time: datetime.datetime
|
||||
path: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class DownloadModel:
|
||||
app_name: str
|
||||
latest_save: SaveGameFile
|
||||
path: str
|
||||
|
||||
|
||||
class WorkerSignals(QObject):
|
||||
finished = pyqtSignal(str, str)
|
||||
|
||||
|
||||
class SaveWorker(QRunnable):
|
||||
signals = WorkerSignals()
|
||||
|
||||
def __init__(self, model: Union[UploadModel, DownloadModel]):
|
||||
super(SaveWorker, self).__init__()
|
||||
self.model = model
|
||||
|
||||
self.setAutoDelete(True)
|
||||
|
||||
def run(self) -> None:
|
||||
try:
|
||||
if isinstance(self.model, DownloadModel):
|
||||
shared.core.download_saves(self.model.app_name, self.model.latest_save.manifest_name, self.model.path)
|
||||
else:
|
||||
shared.core.upload_save(self.model.app_name, self.model.path, self.model.date_time)
|
||||
except Exception as e:
|
||||
self.signals.finished.emit(str(e), self.model.app_name)
|
||||
logger.error(str(e))
|
||||
return
|
||||
self.signals.finished.emit("", self.model.app_name)
|
||||
|
||||
|
||||
class CloudSaveDialog(QDialog, Ui_SyncSaveDialog):
|
||||
DOWNLOAD = 2
|
||||
UPLOAD = 1
|
||||
CANCEL = 0
|
||||
|
||||
def __init__(self, igame: InstalledGame, dt_local: datetime.datetime, dt_remote: datetime.datetime, newer: str):
|
||||
super(CloudSaveDialog, self).__init__()
|
||||
self.setupUi(self)
|
||||
|
||||
self.setAttribute(Qt.WA_DeleteOnClose, True)
|
||||
self.setWindowFlags(Qt.Dialog | Qt.CustomizeWindowHint | Qt.WindowTitleHint)
|
||||
|
||||
self.status = self.CANCEL
|
||||
|
||||
self.title_label.setText(self.title_label.text() + igame.title)
|
||||
|
||||
self.date_info_local.setText(dt_local.strftime("%A, %d. %B %Y %I:%M%p"))
|
||||
self.date_info_remote.setText(dt_remote.strftime("%A, %d. %B %Y %I:%M%p"))
|
||||
|
||||
new_text = self.tr(" (newer)")
|
||||
if newer == "remote":
|
||||
self.cloud_gb.setTitle(self.cloud_gb.title() + new_text)
|
||||
elif newer == "local":
|
||||
self.local_gb.setTitle(self.local_gb.title() + new_text)
|
||||
|
||||
self.icon_local.setPixmap(icon("mdi.harddisk").pixmap(128, 128))
|
||||
self.icon_remote.setPixmap(icon("mdi.cloud-outline").pixmap(128, 128))
|
||||
|
||||
self.upload_button.clicked.connect(lambda: self.btn_clicked(self.UPLOAD))
|
||||
self.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):
|
||||
self.exec_()
|
||||
return self.status
|
||||
|
||||
def btn_clicked(self, status):
|
||||
self.status = status
|
||||
self.close()
|
||||
|
||||
|
||||
class CloudSaveUtils(QObject):
|
||||
sync_finished = pyqtSignal(str)
|
||||
|
||||
def __init__(self):
|
||||
super(CloudSaveUtils, self).__init__()
|
||||
self.core = shared.core
|
||||
saves = shared.api_results.saves
|
||||
|
||||
save_games = set()
|
||||
for igame in self.core.get_installed_list():
|
||||
game = self.core.get_game(igame.app_name)
|
||||
if self.core.is_installed(igame.app_name) and game.supports_cloud_saves:
|
||||
save_games.add(igame.app_name)
|
||||
|
||||
self.latest_saves = dict()
|
||||
for s in sorted(saves, key=lambda a: a.datetime):
|
||||
if s.app_name in save_games:
|
||||
self.latest_saves[s.app_name] = s
|
||||
|
||||
self.thread_pool = QThreadPool.globalInstance()
|
||||
|
||||
def sync_before_launch_game(self, app_name):
|
||||
igame = self.core.get_installed_game(app_name)
|
||||
res, (dt_local, dt_remote) = self.core.check_savegame_state(igame.save_path, self.latest_saves.get(app_name))
|
||||
|
||||
# maybe i will add this
|
||||
# if res == SaveGameStatus.REMOTE_NEWER:
|
||||
# self.download_saves()
|
||||
if res != SaveGameStatus.SAME_AGE:
|
||||
newer = None
|
||||
if res == SaveGameStatus.REMOTE_NEWER:
|
||||
newer = "remote"
|
||||
elif res == SaveGameStatus.LOCAL_NEWER:
|
||||
newer = "local"
|
||||
|
||||
if res == SaveGameStatus.REMOTE_NEWER and not dt_local:
|
||||
self.download_saves(igame)
|
||||
return True
|
||||
|
||||
elif res == SaveGameStatus.LOCAL_NEWER and not dt_remote:
|
||||
self.upload_saves(igame, dt_local)
|
||||
return True
|
||||
|
||||
result = CloudSaveDialog(igame, dt_local, dt_remote, newer).get_action()
|
||||
if result == CloudSaveDialog.UPLOAD:
|
||||
self.upload_saves(igame, dt_local)
|
||||
return
|
||||
elif result == CloudSaveDialog.DOWNLOAD:
|
||||
self.download_saves(igame)
|
||||
elif result == CloudSaveDialog.CANCEL:
|
||||
return False
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def game_finished(self, app_name, exit_code):
|
||||
igame = self.core.get_installed_game(app_name)
|
||||
res, (dt_local, dt_remote) = self.core.check_savegame_state(igame.save_path, self.latest_saves.get(app_name))
|
||||
|
||||
if res == SaveGameStatus.LOCAL_NEWER:
|
||||
if exit_code != 0:
|
||||
reply = QMessageBox.question(None, "Cloud Saves", self.tr(
|
||||
"Game could crashed. Do you want to upload save files? The save files could be corrupt"),
|
||||
buttons=QMessageBox.Yes | QMessageBox.No, defaultButton=QMessageBox.Yes)
|
||||
|
||||
if reply == QMessageBox.No:
|
||||
self.sync_finished.emit(app_name)
|
||||
return
|
||||
|
||||
self.upload_saves(igame, dt_local)
|
||||
return
|
||||
|
||||
elif res == SaveGameStatus.NO_SAVE:
|
||||
QMessageBox.warning(None, "No saves", self.tr(
|
||||
"There are no saves local and online. Maybe you have to change save path of {}").format(igame.title))
|
||||
return
|
||||
|
||||
elif res == SaveGameStatus.SAME_AGE:
|
||||
return
|
||||
|
||||
# Remote newer
|
||||
newer = None
|
||||
if res == SaveGameStatus.REMOTE_NEWER:
|
||||
newer = "remote"
|
||||
result = CloudSaveDialog(igame, dt_local, dt_remote, newer).get_action()
|
||||
if result == CloudSaveDialog.UPLOAD:
|
||||
self.upload_saves(igame, dt_local)
|
||||
elif result == CloudSaveDialog.DOWNLOAD:
|
||||
self.download_saves(igame)
|
||||
|
||||
def upload_saves(self, igame: InstalledGame, dt_local):
|
||||
logger.info("Uploading saves for " + igame.title)
|
||||
w = SaveWorker(UploadModel(igame.app_name, dt_local, igame.save_path))
|
||||
w.signals.finished.connect(self.worker_finished)
|
||||
self.thread_pool.start(w)
|
||||
|
||||
def download_saves(self, igame):
|
||||
logger.info("Downloading saves for " + igame.title)
|
||||
w = SaveWorker(DownloadModel(igame.app_name, self.latest_saves.get(igame.app_name), igame.save_path))
|
||||
w.signals.finished.connect(self.worker_finished)
|
||||
self.thread_pool.start(w)
|
||||
|
||||
def worker_finished(self, error_message: str, app_name: str):
|
||||
if not error_message:
|
||||
self.sync_finished.emit(app_name)
|
||||
else:
|
||||
QMessageBox.warning(None, "Warning", self.tr("Syncing with cloud failed: \n ") + error_message)
|
||||
self.sync_finished.emit(app_name)
|
|
@ -27,7 +27,7 @@ class GameInfoTabs(SideTabWidget):
|
|||
|
||||
self.tabBar().setCurrentIndex(1)
|
||||
|
||||
def update_game(self, game: Game, dlcs: list):
|
||||
def update_game(self, game: Game):
|
||||
self.setCurrentIndex(1)
|
||||
self.info.update_game(game)
|
||||
self.settings.update_game(game)
|
||||
|
|
|
@ -3,7 +3,7 @@ import platform
|
|||
from typing import Tuple
|
||||
|
||||
from PyQt5.QtCore import QSettings
|
||||
from PyQt5.QtWidgets import QWidget, QFileDialog
|
||||
from PyQt5.QtWidgets import QWidget, QFileDialog, QLabel
|
||||
|
||||
from legendary.core import LegendaryCore
|
||||
from legendary.models.game import InstalledGame, Game
|
||||
|
@ -47,6 +47,13 @@ class GameSettings(QWidget, Ui_GameSettings):
|
|||
|
||||
self.core = core
|
||||
self.settings = QSettings()
|
||||
|
||||
self.cloud_save_path_edit = PathEdit("", file_type=QFileDialog.DirectoryOnly,
|
||||
ph_text=self.tr("Cloud save path"),
|
||||
edit_func=lambda text: (os.path.exists(text), text),
|
||||
save_func=self.save_save_path)
|
||||
self.cloud_gb.layout().addRow(QLabel(self.tr("Save path")), self.cloud_save_path_edit)
|
||||
|
||||
self.offline.currentIndexChanged.connect(
|
||||
lambda x: self.update_combobox(x, "offline")
|
||||
)
|
||||
|
@ -85,7 +92,12 @@ class GameSettings(QWidget, Ui_GameSettings):
|
|||
else:
|
||||
self.proton_groupbox.setVisible(False)
|
||||
|
||||
# startparams, skip_update_check
|
||||
# skip_update_check
|
||||
|
||||
def save_save_path(self, text):
|
||||
if self.game.supports_cloud_saves and not self.change:
|
||||
self.igame.save_path = text
|
||||
self.core.lgd.set_installed_game(self.igame.app_name, self.igame)
|
||||
|
||||
def save_line_edit(self, option, value):
|
||||
if value:
|
||||
|
@ -211,7 +223,7 @@ class GameSettings(QWidget, Ui_GameSettings):
|
|||
self.game_title.setText(f"<h2>{self.game.app_title}</h2>")
|
||||
if platform.system() != "Windows":
|
||||
self.linux_settings.update_game(app_name)
|
||||
self.linux_settings.dxvk.update_settings(app_name)
|
||||
|
||||
proton = self.core.lgd.config.get(f"{app_name}", "wrapper", fallback="").replace('"', "")
|
||||
if proton != "":
|
||||
self.proton_prefix.setEnabled(True)
|
||||
|
@ -227,11 +239,16 @@ class GameSettings(QWidget, Ui_GameSettings):
|
|||
self.wrapper_widget.setEnabled(True)
|
||||
|
||||
if not self.game.supports_cloud_saves:
|
||||
self.cloud_sync.setEnabled(False)
|
||||
self.cloud_gb.setEnabled(False)
|
||||
self.cloud_save_path_edit.setText("")
|
||||
else:
|
||||
self.cloud_sync.setEnabled(True)
|
||||
self.cloud_gb.setEnabled(True)
|
||||
sync_cloud = self.settings.value(f"{self.game.app_name}/auto_sync_cloud", True, bool)
|
||||
self.cloud_sync.setChecked(sync_cloud)
|
||||
if self.igame.save_path:
|
||||
self.cloud_save_path_edit.setText(self.igame.save_path)
|
||||
else:
|
||||
self.cloud_save_path_edit.setText("")
|
||||
|
||||
self.launch_params.setText(self.core.lgd.config.get(self.game.app_name, "start_params", fallback=""))
|
||||
self.change = True
|
||||
|
@ -245,5 +262,6 @@ class LinuxAppSettings(LinuxSettings):
|
|||
self.name = app_name
|
||||
self.wine_prefix.setText(self.core.lgd.config.get(self.name, "wine_prefix", fallback=""))
|
||||
self.wine_exec.setText(self.core.lgd.config.get(self.name, "wine_executable", fallback=""))
|
||||
|
||||
self.dxvk.name = app_name
|
||||
self.dxvk.more_settings_widget.name = app_name
|
||||
self.dxvk.load_settings()
|
||||
|
|
|
@ -7,7 +7,7 @@ from PyQt5.QtCore import pyqtSignal, QProcess, QSettings, Qt, QByteArray, QProce
|
|||
from PyQt5.QtGui import QPixmap
|
||||
from PyQt5.QtWidgets import QGroupBox, QMessageBox, QAction, QLabel, QPushButton
|
||||
|
||||
from legendary.models.game import InstalledGame, Game
|
||||
from legendary.models.game import Game
|
||||
from rare import shared
|
||||
from rare.components.dialogs.uninstall_dialog import UninstallDialog
|
||||
from rare.components.extra.console import ConsoleWindow
|
||||
|
@ -18,29 +18,32 @@ logger = getLogger("Game")
|
|||
|
||||
|
||||
class BaseInstalledWidget(QGroupBox):
|
||||
launch_signal = pyqtSignal(str)
|
||||
launch_signal = pyqtSignal(str, QProcess, list)
|
||||
show_info = pyqtSignal(Game)
|
||||
finish_signal = pyqtSignal(str)
|
||||
finish_signal = pyqtSignal(str, int)
|
||||
update_list = pyqtSignal()
|
||||
proc: QProcess()
|
||||
sync_game = pyqtSignal(str)
|
||||
|
||||
def __init__(self, igame: InstalledGame, pixmap: QPixmap, is_origin: bool = False, game: Game = None):
|
||||
def __init__(self, app_name, pixmap: QPixmap):
|
||||
super(BaseInstalledWidget, self).__init__()
|
||||
self.igame = igame
|
||||
self.is_origin = is_origin
|
||||
self.core = shared.core
|
||||
if not game:
|
||||
self.game = self.core.get_game(self.igame.app_name)
|
||||
|
||||
self.game = self.core.get_game(app_name)
|
||||
if self.game.third_party_store != "Origin":
|
||||
self.igame = self.core.get_installed_game(app_name)
|
||||
self.is_origin = False
|
||||
else:
|
||||
self.game = game
|
||||
self.is_origin = True
|
||||
|
||||
self.image = QLabel()
|
||||
self.image.setPixmap(pixmap.scaled(200, int(200 * 4 / 3), transformMode=Qt.SmoothTransformation))
|
||||
self.game_running = False
|
||||
self.offline = shared.args.offline
|
||||
if is_origin:
|
||||
if self.game.third_party_store == "Origin":
|
||||
self.update_available = False
|
||||
else:
|
||||
self.update_available = self.core.get_asset(self.game.app_name, False).build_version != igame.version
|
||||
self.update_available = self.core.get_asset(self.game.app_name, False).build_version != self.igame.version
|
||||
self.data = QByteArray()
|
||||
self.setContentsMargins(0, 0, 0, 0)
|
||||
self.settings = QSettings()
|
||||
|
@ -50,12 +53,17 @@ class BaseInstalledWidget(QGroupBox):
|
|||
launch.triggered.connect(self.launch)
|
||||
self.addAction(launch)
|
||||
|
||||
if self.game.supports_cloud_saves:
|
||||
sync = QAction(self.tr("Sync with cloud"), self)
|
||||
sync.triggered.connect(lambda: self.sync_game.emit(self.game.app_name))
|
||||
self.addAction(sync)
|
||||
|
||||
if os.path.exists(os.path.expanduser(f"~/Desktop/{self.game.app_title}.desktop")) \
|
||||
or os.path.exists(os.path.expanduser(f"~/Desktop/{self.game.app_title}.lnk")):
|
||||
self.create_desktop = QAction(self.tr("Remove Desktop link"))
|
||||
else:
|
||||
self.create_desktop = QAction(self.tr("Create Desktop link"))
|
||||
if not is_origin:
|
||||
if not self.is_origin:
|
||||
self.create_desktop.triggered.connect(lambda: self.create_desktop_link("desktop"))
|
||||
self.addAction(self.create_desktop)
|
||||
|
||||
|
@ -69,7 +77,7 @@ class BaseInstalledWidget(QGroupBox):
|
|||
self.create_start_menu = QAction(self.tr("Remove start menu link"))
|
||||
else:
|
||||
self.create_start_menu = QAction(self.tr("Create start menu link"))
|
||||
if not is_origin:
|
||||
if not self.is_origin:
|
||||
self.create_start_menu.triggered.connect(lambda: self.create_desktop_link("start_menu"))
|
||||
self.addAction(self.create_start_menu)
|
||||
|
||||
|
@ -185,9 +193,8 @@ class BaseInstalledWidget(QGroupBox):
|
|||
self.proc.readyReadStandardOutput.connect(self.stdout)
|
||||
self.proc.readyReadStandardError.connect(self.stderr)
|
||||
|
||||
self.proc.start(params[0], params[1:])
|
||||
self.launch_signal.emit(self.game.app_name)
|
||||
self.game_running = True
|
||||
self.launch_signal.emit(self.game.app_name, self.proc, params)
|
||||
# self.game_running = True
|
||||
|
||||
return 0
|
||||
|
||||
|
@ -214,7 +221,7 @@ class BaseInstalledWidget(QGroupBox):
|
|||
if resp == 0:
|
||||
webbrowser.open("https://www.dm.origin.com/download")
|
||||
|
||||
self.finish_signal.emit(self.game.app_name)
|
||||
self.finish_signal.emit(self.game.app_name, exit_code)
|
||||
self.game_running = False
|
||||
if self.settings.value("show_console", False, bool):
|
||||
self.console.log(f"Game exited with code: {exit_code}")
|
||||
|
|
|
@ -5,7 +5,6 @@ from PyQt5.QtGui import QMouseEvent
|
|||
from PyQt5.QtWidgets import QVBoxLayout, QHBoxLayout, QPushButton, QLabel
|
||||
from qtawesome import icon
|
||||
|
||||
from legendary.models.game import InstalledGame, Game
|
||||
from rare import shared
|
||||
from rare.components.tabs.games.game_widgets.base_installed_widget import BaseInstalledWidget
|
||||
|
||||
|
@ -15,9 +14,8 @@ logger = getLogger("GameWidgetInstalled")
|
|||
class InstalledIconWidget(BaseInstalledWidget):
|
||||
update_game = pyqtSignal()
|
||||
|
||||
def __init__(self, igame: InstalledGame, pixmap, is_origin: bool = False,
|
||||
game: Game = None):
|
||||
super(InstalledIconWidget, self).__init__(igame, pixmap, is_origin, game)
|
||||
def __init__(self, app_name, pixmap):
|
||||
super(InstalledIconWidget, self).__init__(app_name, pixmap)
|
||||
self.setObjectName("game_widget_icon")
|
||||
|
||||
self.setContextMenuPolicy(Qt.ActionsContextMenu)
|
||||
|
@ -32,7 +30,7 @@ class InstalledIconWidget(BaseInstalledWidget):
|
|||
|
||||
self.layout.addWidget(self.image)
|
||||
|
||||
self.title_label = QLabel(f"<h4>{game.app_title}</h4>")
|
||||
self.title_label = QLabel(f"<h4>{self.game.app_title}</h4>")
|
||||
self.title_label.setAutoFillBackground(False)
|
||||
self.title_label.setWordWrap(True)
|
||||
self.title_label.setFixedWidth(175)
|
||||
|
|
|
@ -4,7 +4,6 @@ from PyQt5.QtCore import QProcess, pyqtSignal
|
|||
from PyQt5.QtWidgets import QHBoxLayout, QLabel, QPushButton, QVBoxLayout
|
||||
from qtawesome import icon
|
||||
|
||||
from legendary.models.game import InstalledGame, Game
|
||||
from rare.components.tabs.games.game_widgets.base_installed_widget import BaseInstalledWidget
|
||||
|
||||
logger = getLogger("GameWidget")
|
||||
|
@ -15,12 +14,12 @@ class InstalledListWidget(BaseInstalledWidget):
|
|||
signal = pyqtSignal(str)
|
||||
update_game = pyqtSignal()
|
||||
|
||||
def __init__(self, igame: InstalledGame, pixmap, is_origin: bool = False, game: Game = None):
|
||||
super(InstalledListWidget, self).__init__(igame, pixmap, is_origin, game)
|
||||
def __init__(self, app_name, pixmap):
|
||||
super(InstalledListWidget, self).__init__(app_name, pixmap)
|
||||
self.dev = self.game.metadata["developer"]
|
||||
if not is_origin:
|
||||
self.size = igame.install_size
|
||||
self.launch_params = igame.launch_parameters
|
||||
if self.game.third_party_store != "Origin":
|
||||
self.size = self.igame.install_size
|
||||
self.launch_params = self.igame.launch_parameters
|
||||
else:
|
||||
self.size = 0
|
||||
self.launch_params = ""
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
from logging import getLogger
|
||||
|
||||
from PyQt5.QtCore import pyqtSignal
|
||||
from PyQt5.QtWidgets import QGroupBox
|
||||
from PyQt5.QtWidgets import QWidget, QCheckBox, QVBoxLayout, QWidgetAction, QMenu, QToolButton, QHBoxLayout
|
||||
|
||||
from legendary.core import LegendaryCore
|
||||
from rare import shared
|
||||
from rare.ui.components.tabs.settings.dxvk import Ui_DxvkSettings
|
||||
|
||||
|
@ -65,7 +62,6 @@ class DxvkSettings(QGroupBox, Ui_DxvkSettings):
|
|||
show_dxvk_index = self.show_dxvk.currentIndex()
|
||||
if show_dxvk_index:
|
||||
if f"{self.name}.env" not in self.core.lgd.config.sections():
|
||||
print("add section dxvk")
|
||||
self.core.lgd.config.add_section(f"{self.name}.env")
|
||||
if show_dxvk_index == 1:
|
||||
self.core.lgd.config[f"{self.name}.env"]["DXVK_HUD"] = "0"
|
||||
|
@ -93,139 +89,3 @@ class DxvkSettings(QGroupBox, Ui_DxvkSettings):
|
|||
self.core.lgd.config.remove_section(f"{self.name}.env")
|
||||
self.core.lgd.save_config()
|
||||
self.load_settings()
|
||||
|
||||
|
||||
class DxvkWidget(QGroupBox):
|
||||
|
||||
def __init__(self, name=None):
|
||||
super(DxvkWidget, self).__init__()
|
||||
self.core = shared.core
|
||||
self.setObjectName("settings_widget")
|
||||
self.dxvk_settings = {
|
||||
"fps": [False, "Fps"],
|
||||
"gpuload": [False, self.tr("GPU usage")],
|
||||
"memory": [False, self.tr("Used Memory")],
|
||||
"devinfo": [False, self.tr("Device info")],
|
||||
"version": [False, self.tr("DXVK version")],
|
||||
"api": [False, self.tr("D3D Level of application")],
|
||||
"frametime": [False, self.tr("Frame time graph")]
|
||||
}
|
||||
self.name = name
|
||||
self.layout = QVBoxLayout()
|
||||
self.child_layout = QHBoxLayout()
|
||||
self.setTitle(self.tr("dxvk settings"))
|
||||
self.show_dxvk = QCheckBox("Show Dxvk HUD")
|
||||
|
||||
self.more_settings = QToolButton()
|
||||
dxvk_hud = self.core.lgd.config.get(f"{self.name}.env", "DXVK_HUD", fallback="")
|
||||
|
||||
self.more_settings.setDisabled(not dxvk_hud == "")
|
||||
if dxvk_hud:
|
||||
for s in dxvk_hud.split(","):
|
||||
self.dxvk_settings[s][0] = True
|
||||
|
||||
self.more_settings.setPopupMode(QToolButton.InstantPopup)
|
||||
self.more_settings.setMenu(QMenu())
|
||||
self.more_settings.setText("More DXVK settings")
|
||||
|
||||
action = QWidgetAction(self)
|
||||
self.more_settings_widget = DxvkMoreSettingsWidget(self.dxvk_settings, self.core)
|
||||
self.more_settings_widget.show_dxvk.connect(lambda x: self.show_dxvk.setChecked(x))
|
||||
action.setDefaultWidget(self.more_settings_widget)
|
||||
self.more_settings.menu().addAction(action)
|
||||
|
||||
self.show_dxvk.stateChanged.connect(self.update_dxvk_active)
|
||||
self.show_dxvk.setChecked(not dxvk_hud == "")
|
||||
self.child_layout.addWidget(self.show_dxvk)
|
||||
|
||||
self.child_layout.addWidget(self.more_settings)
|
||||
self.layout.addLayout(self.child_layout)
|
||||
|
||||
self.setLayout(self.layout)
|
||||
|
||||
def update_settings(self, app_name):
|
||||
self.name = app_name
|
||||
dxvk_hud = self.core.lgd.config.get(f"{self.name}.env", "DXVK_HUD", fallback="")
|
||||
if dxvk_hud:
|
||||
self.more_settings.setDisabled(False)
|
||||
for s in dxvk_hud.split(","):
|
||||
self.dxvk_settings[s][0] = True
|
||||
else:
|
||||
self.show_dxvk.setChecked(False)
|
||||
self.more_settings.setDisabled(True)
|
||||
|
||||
def update_dxvk_active(self):
|
||||
if self.show_dxvk.isChecked():
|
||||
if not f"{self.name}.env" in self.core.lgd.config.sections():
|
||||
print("add section dxvk")
|
||||
self.core.lgd.config.add_section(f"{self.name}.env")
|
||||
self.more_settings.setDisabled(False)
|
||||
|
||||
for i in self.more_settings_widget.settings:
|
||||
if i in ["fps", "gpuload"]:
|
||||
self.more_settings_widget.settings[i][0] = True
|
||||
|
||||
self.core.lgd.config[f"{self.name}.env"]["DXVK_HUD"] = "fps,gpuload"
|
||||
for w in self.more_settings_widget.widgets:
|
||||
if w.tag == "fps" or w.tag == "gpuload":
|
||||
w.setChecked(True)
|
||||
|
||||
else:
|
||||
w.setChecked(False)
|
||||
else:
|
||||
self.more_settings.setDisabled(True)
|
||||
if not self.core.lgd.config.get(f"{self.name}.env", "DXVK_HUD", fallback="") == "":
|
||||
self.core.lgd.config.remove_option(f"{self.name}.env", "DXVK_HUD")
|
||||
if not self.core.lgd.config[f"{self.name}.env"]:
|
||||
self.core.lgd.config.remove_section(f"{self.name}.env")
|
||||
self.core.lgd.save_config()
|
||||
|
||||
|
||||
class DxvkMoreSettingsWidget(QWidget):
|
||||
show_dxvk = pyqtSignal(bool)
|
||||
|
||||
def __init__(self, settings: dict, core: LegendaryCore):
|
||||
super(DxvkMoreSettingsWidget, self).__init__()
|
||||
self.layout = QVBoxLayout()
|
||||
self.name = "default"
|
||||
self.widgets = []
|
||||
self.core = core
|
||||
self.settings = settings
|
||||
for i in settings:
|
||||
widget = CheckBox(i, settings[i])
|
||||
widget.signal.connect(self.change)
|
||||
self.layout.addWidget(widget)
|
||||
self.widgets.append(widget)
|
||||
|
||||
self.setLayout(self.layout)
|
||||
|
||||
def change(self, signal: list):
|
||||
tag, checked = signal
|
||||
self.settings[tag][0] = checked
|
||||
|
||||
sett = []
|
||||
logger.debug(self.settings)
|
||||
for i in self.settings:
|
||||
check, _ = self.settings[i]
|
||||
if check:
|
||||
sett.append(i)
|
||||
if len(sett) > 0:
|
||||
self.core.lgd.config.set(f"{self.name}.env", "DXVK_HUD", ",".join(sett))
|
||||
|
||||
else:
|
||||
self.core.lgd.config.remove_option(f"{self.name}.env", "DXVK_HUD")
|
||||
self.show_dxvk.emit(False)
|
||||
if not self.core.lgd.config.options(f"{self.name}.env"):
|
||||
self.core.lgd.config.remove_section(f"{self.name}.env")
|
||||
self.core.lgd.save_config()
|
||||
|
||||
|
||||
class CheckBox(QCheckBox):
|
||||
signal = pyqtSignal(tuple)
|
||||
|
||||
def __init__(self, tag, settings):
|
||||
checked, text = settings
|
||||
super(CheckBox, self).__init__(text)
|
||||
self.setChecked(checked)
|
||||
self.tag = tag
|
||||
self.clicked.connect(lambda: self.signal.emit((self.tag, self.isChecked())))
|
||||
|
|
|
@ -3,7 +3,7 @@ from logging import getLogger
|
|||
from PyQt5.QtWidgets import QFileDialog, QWidget
|
||||
|
||||
from rare import shared
|
||||
from rare.components.tabs.settings.dxvk import DxvkSettings, DxvkWidget
|
||||
from rare.components.tabs.settings.dxvk import DxvkSettings
|
||||
from rare.ui.components.tabs.settings.linux import Ui_LinuxSettings
|
||||
from rare.utils.extra_widgets import PathEdit
|
||||
|
||||
|
@ -32,11 +32,7 @@ class LinuxSettings(QWidget, Ui_LinuxSettings):
|
|||
self.exec_layout.addWidget(self.wine_exec)
|
||||
|
||||
# dxvk
|
||||
# FIXME: Remove this check when done with per game settings
|
||||
if name is None:
|
||||
self.dxvk = DxvkSettings(self.name)
|
||||
else:
|
||||
self.dxvk = DxvkWidget()
|
||||
self.dxvk = DxvkSettings(self.name)
|
||||
self.dxvk_layout.addWidget(self.dxvk)
|
||||
|
||||
def save_setting(self, text: str, setting_name: str):
|
||||
|
|
|
@ -4,14 +4,12 @@ from qtawesome import icon
|
|||
|
||||
from rare import shared
|
||||
from rare.components.tabs.account import MiniWidget
|
||||
from rare.components.tabs.cloud_saves import SyncSaves
|
||||
from rare.components.tabs.downloads import DownloadTab
|
||||
from rare.components.tabs.games import GamesTab
|
||||
from rare.components.tabs.settings import SettingsTab
|
||||
from rare.components.tabs.settings.debug import DebugSettings
|
||||
from rare.components.tabs.shop import Shop
|
||||
from rare.components.tabs.tab_utils import TabBar, TabButtonWidget
|
||||
from rare.utils.models import InstallOptionsModel
|
||||
|
||||
|
||||
class TabWidget(QTabWidget):
|
||||
|
@ -19,7 +17,7 @@ class TabWidget(QTabWidget):
|
|||
|
||||
def __init__(self, parent):
|
||||
super(TabWidget, self).__init__(parent=parent)
|
||||
disabled_tab = 4 if not shared.args.offline else 1
|
||||
disabled_tab = 3 if not shared.args.offline else 1
|
||||
self.core = shared.core
|
||||
self.signals = shared.signals
|
||||
self.setTabBar(TabBar(disabled_tab))
|
||||
|
@ -31,8 +29,6 @@ class TabWidget(QTabWidget):
|
|||
self.downloadTab = DownloadTab(self.games_tab.updates)
|
||||
self.addTab(self.downloadTab, "Downloads" + (
|
||||
" (" + str(len(self.games_tab.updates)) + ")" if len(self.games_tab.updates) != 0 else ""))
|
||||
self.cloud_saves = SyncSaves()
|
||||
self.addTab(self.cloud_saves, "Cloud Saves")
|
||||
self.store = Shop(self.core)
|
||||
self.addTab(self.store, self.tr("Store (Beta)"))
|
||||
self.settings = SettingsTab(self)
|
||||
|
@ -65,19 +61,6 @@ class TabWidget(QTabWidget):
|
|||
|
||||
# update dl tab text
|
||||
self.signals.update_download_tab_text.connect(self.update_dl_tab_text)
|
||||
# imported
|
||||
# shared.signals.update_gamelist.connect(self.game_imported)
|
||||
|
||||
if not shared.args.offline:
|
||||
# install dlc
|
||||
self.games_tab.game_info_tabs.dlc.install_dlc.connect(
|
||||
lambda app_name, update: self.install_game(
|
||||
InstallOptionsModel(app_name=app_name),
|
||||
update=update))
|
||||
|
||||
# Finished sync
|
||||
self.cloud_saves.finished.connect(self.finished_sync)
|
||||
# Game finished
|
||||
|
||||
# Open game list on click on Games tab button
|
||||
self.tabBarClicked.connect(self.mouse_clicked)
|
||||
|
|
94
rare/ui/components/dialogs/sync_save_dialog.py
Normal file
94
rare/ui/components/dialogs/sync_save_dialog.py
Normal file
|
@ -0,0 +1,94 @@
|
|||
# -*- 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.5
|
||||
#
|
||||
# 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, 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.horizontalLayout = QtWidgets.QHBoxLayout()
|
||||
self.horizontalLayout.setObjectName("horizontalLayout")
|
||||
self.local_gb = QtWidgets.QGroupBox(SyncSaveDialog)
|
||||
self.local_gb.setObjectName("local_gb")
|
||||
self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.local_gb)
|
||||
self.verticalLayout_2.setObjectName("verticalLayout_2")
|
||||
self.date_info_local = QtWidgets.QLabel(self.local_gb)
|
||||
self.date_info_local.setText("TextLabel")
|
||||
self.date_info_local.setObjectName("date_info_local")
|
||||
self.verticalLayout_2.addWidget(self.date_info_local)
|
||||
self.icon_local = QtWidgets.QLabel(self.local_gb)
|
||||
self.icon_local.setText("")
|
||||
self.icon_local.setObjectName("icon_local")
|
||||
self.verticalLayout_2.addWidget(self.icon_local)
|
||||
self.upload_button = QtWidgets.QPushButton(self.local_gb)
|
||||
self.upload_button.setObjectName("upload_button")
|
||||
self.verticalLayout_2.addWidget(self.upload_button)
|
||||
self.horizontalLayout.addWidget(self.local_gb)
|
||||
self.cloud_gb = QtWidgets.QGroupBox(SyncSaveDialog)
|
||||
self.cloud_gb.setObjectName("cloud_gb")
|
||||
self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.cloud_gb)
|
||||
self.verticalLayout_3.setObjectName("verticalLayout_3")
|
||||
self.date_info_remote = QtWidgets.QLabel(self.cloud_gb)
|
||||
self.date_info_remote.setText("TextLabel")
|
||||
self.date_info_remote.setObjectName("date_info_remote")
|
||||
self.verticalLayout_3.addWidget(self.date_info_remote)
|
||||
self.icon_remote = QtWidgets.QLabel(self.cloud_gb)
|
||||
self.icon_remote.setText("")
|
||||
self.icon_remote.setObjectName("icon_remote")
|
||||
self.verticalLayout_3.addWidget(self.icon_remote)
|
||||
self.download_button = QtWidgets.QPushButton(self.cloud_gb)
|
||||
self.download_button.setObjectName("download_button")
|
||||
self.verticalLayout_3.addWidget(self.download_button)
|
||||
self.horizontalLayout.addWidget(self.cloud_gb)
|
||||
self.verticalLayout.addLayout(self.horizontalLayout)
|
||||
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)
|
||||
QtCore.QMetaObject.connectSlotsByName(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.local_gb.setTitle(_translate("SyncSaveDialog", "Local"))
|
||||
self.upload_button.setText(_translate("SyncSaveDialog", "Upload"))
|
||||
self.cloud_gb.setTitle(_translate("SyncSaveDialog", "Cloud"))
|
||||
self.download_button.setText(_translate("SyncSaveDialog", "Download"))
|
||||
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_())
|
122
rare/ui/components/dialogs/sync_save_dialog.ui
Normal file
122
rare/ui/components/dialogs/sync_save_dialog.ui
Normal file
|
@ -0,0 +1,122 @@
|
|||
<?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="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="local_gb">
|
||||
<property name="title">
|
||||
<string>Local</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="date_info_local">
|
||||
<property name="text">
|
||||
<string notr="true">TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="icon_local">
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="upload_button">
|
||||
<property name="text">
|
||||
<string>Upload</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="cloud_gb">
|
||||
<property name="title">
|
||||
<string>Cloud</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="date_info_remote">
|
||||
<property name="text">
|
||||
<string notr="true">TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="icon_remote">
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="download_button">
|
||||
<property name="text">
|
||||
<string>Download</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</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>
|
|
@ -2,13 +2,13 @@
|
|||
|
||||
# Form implementation generated from reading ui file 'rare/ui/components/tabs/games/game_info/game_settings.ui'
|
||||
#
|
||||
# Created by: PyQt5 UI code generator 5.15.4
|
||||
# Created by: PyQt5 UI code generator 5.15.5
|
||||
#
|
||||
# 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
|
||||
from PyQt5 import QtCore, QtWidgets
|
||||
|
||||
|
||||
class Ui_GameSettings(object):
|
||||
|
@ -55,16 +55,9 @@ class Ui_GameSettings(object):
|
|||
self.offline.addItem("")
|
||||
self.offline.addItem("")
|
||||
self.launch_settings_layout.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.offline)
|
||||
self.cloud_sync_label = QtWidgets.QLabel(self.launch_settings_groupbox)
|
||||
self.cloud_sync_label.setObjectName("cloud_sync_label")
|
||||
self.launch_settings_layout.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.cloud_sync_label)
|
||||
self.cloud_sync = QtWidgets.QCheckBox(self.launch_settings_groupbox)
|
||||
self.cloud_sync.setText("")
|
||||
self.cloud_sync.setObjectName("cloud_sync")
|
||||
self.launch_settings_layout.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.cloud_sync)
|
||||
self.launch_params_label = QtWidgets.QLabel(self.launch_settings_groupbox)
|
||||
self.launch_params_label.setObjectName("launch_params_label")
|
||||
self.launch_settings_layout.setWidget(3, QtWidgets.QFormLayout.LabelRole, self.launch_params_label)
|
||||
self.launch_settings_layout.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.launch_params_label)
|
||||
self.launch_params_widget = QtWidgets.QWidget(self.launch_settings_groupbox)
|
||||
self.launch_params_widget.setObjectName("launch_params_widget")
|
||||
self.launch_params_layout = QtWidgets.QHBoxLayout(self.launch_params_widget)
|
||||
|
@ -77,10 +70,10 @@ class Ui_GameSettings(object):
|
|||
self.launch_params_button = QtWidgets.QPushButton(self.launch_params_widget)
|
||||
self.launch_params_button.setObjectName("launch_params_button")
|
||||
self.launch_params_layout.addWidget(self.launch_params_button)
|
||||
self.launch_settings_layout.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.launch_params_widget)
|
||||
self.launch_settings_layout.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.launch_params_widget)
|
||||
self.wrapper_label = QtWidgets.QLabel(self.launch_settings_groupbox)
|
||||
self.wrapper_label.setObjectName("wrapper_label")
|
||||
self.launch_settings_layout.setWidget(4, QtWidgets.QFormLayout.LabelRole, self.wrapper_label)
|
||||
self.launch_settings_layout.setWidget(3, QtWidgets.QFormLayout.LabelRole, self.wrapper_label)
|
||||
self.wrapper_widget = QtWidgets.QWidget(self.launch_settings_groupbox)
|
||||
self.wrapper_widget.setObjectName("wrapper_widget")
|
||||
self.wrapper_layout = QtWidgets.QHBoxLayout(self.wrapper_widget)
|
||||
|
@ -93,7 +86,7 @@ class Ui_GameSettings(object):
|
|||
self.wrapper_button = QtWidgets.QPushButton(self.wrapper_widget)
|
||||
self.wrapper_button.setObjectName("wrapper_button")
|
||||
self.wrapper_layout.addWidget(self.wrapper_button)
|
||||
self.launch_settings_layout.setWidget(4, QtWidgets.QFormLayout.FieldRole, self.wrapper_widget)
|
||||
self.launch_settings_layout.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.wrapper_widget)
|
||||
self.game_settings_layout.addWidget(self.launch_settings_groupbox, 0, QtCore.Qt.AlignTop)
|
||||
self.proton_groupbox = QtWidgets.QGroupBox(GameSettings)
|
||||
self.proton_groupbox.setObjectName("proton_groupbox")
|
||||
|
@ -123,6 +116,18 @@ class Ui_GameSettings(object):
|
|||
self.linux_layout.setObjectName("linux_layout")
|
||||
self.proton_layout.setLayout(3, QtWidgets.QFormLayout.SpanningRole, self.linux_layout)
|
||||
self.game_settings_layout.addWidget(self.proton_groupbox, 0, QtCore.Qt.AlignTop)
|
||||
self.cloud_gb = QtWidgets.QGroupBox(GameSettings)
|
||||
self.cloud_gb.setObjectName("cloud_gb")
|
||||
self.formLayout = QtWidgets.QFormLayout(self.cloud_gb)
|
||||
self.formLayout.setObjectName("formLayout")
|
||||
self.cloud_sync_label = QtWidgets.QLabel(self.cloud_gb)
|
||||
self.cloud_sync_label.setObjectName("cloud_sync_label")
|
||||
self.formLayout.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.cloud_sync_label)
|
||||
self.cloud_sync = QtWidgets.QCheckBox(self.cloud_gb)
|
||||
self.cloud_sync.setText("")
|
||||
self.cloud_sync.setObjectName("cloud_sync")
|
||||
self.formLayout.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.cloud_sync)
|
||||
self.game_settings_layout.addWidget(self.cloud_gb)
|
||||
spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
|
||||
self.game_settings_layout.addItem(spacerItem)
|
||||
|
||||
|
@ -141,7 +146,6 @@ class Ui_GameSettings(object):
|
|||
self.offline.setItemText(0, _translate("GameSettings", "Default"))
|
||||
self.offline.setItemText(1, _translate("GameSettings", "Yes"))
|
||||
self.offline.setItemText(2, _translate("GameSettings", "No"))
|
||||
self.cloud_sync_label.setText(_translate("GameSettings", "Sync with cloud"))
|
||||
self.launch_params_label.setText(_translate("GameSettings", "Launch parameters"))
|
||||
self.launch_params.setPlaceholderText(_translate("GameSettings", "parameters"))
|
||||
self.launch_params_button.setText(_translate("GameSettings", "Save"))
|
||||
|
@ -152,6 +156,8 @@ class Ui_GameSettings(object):
|
|||
self.proton_wrapper_label.setText(_translate("GameSettings", "Proton"))
|
||||
self.proton_wrapper.setItemText(0, _translate("GameSettings", "Don\'t use Proton"))
|
||||
self.proton_prefix_label.setText(_translate("GameSettings", "Prefix"))
|
||||
self.cloud_gb.setTitle(_translate("GameSettings", "Cloud Saves"))
|
||||
self.cloud_sync_label.setText(_translate("GameSettings", "Sync with cloud"))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
@ -98,37 +98,23 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="cloud_sync_label">
|
||||
<property name="text">
|
||||
<string>Sync with cloud</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="cloud_sync">
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="launch_params_label">
|
||||
<property name="text">
|
||||
<string>Launch parameters</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QWidget" name="launch_params_widget" native="true">
|
||||
<layout class="QHBoxLayout" name="launch_params_layout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
<item row="2" column="1">
|
||||
<widget class="QWidget" name="launch_params_widget" native="true">
|
||||
<layout class="QHBoxLayout" name="launch_params_layout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
|
@ -156,24 +142,24 @@
|
|||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="wrapper_label">
|
||||
<property name="text">
|
||||
<string>Wrapper</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QWidget" name="wrapper_widget" native="true">
|
||||
<layout class="QHBoxLayout" name="wrapper_layout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="wrapper_label">
|
||||
<property name="text">
|
||||
<string>Wrapper</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QWidget" name="wrapper_widget" native="true">
|
||||
<layout class="QHBoxLayout" name="wrapper_layout">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
|
@ -246,28 +232,51 @@
|
|||
<layout class="QVBoxLayout" name="proton_prefix_layout"/>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<layout class="QVBoxLayout" name="linux_layout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</layout>
|
||||
<layout class="QVBoxLayout" name="linux_layout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="game_settings_vspacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="cloud_gb">
|
||||
<property name="title">
|
||||
<string>Cloud Saves</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<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>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="game_settings_vspacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
|
|
|
@ -100,6 +100,7 @@ class ApiResults:
|
|||
mac_games: list = None
|
||||
assets: list = None
|
||||
no_asset_games: list = None
|
||||
saves: list = None
|
||||
|
||||
def __bool__(self):
|
||||
return self.game_list is not None \
|
||||
|
@ -107,7 +108,8 @@ class ApiResults:
|
|||
and self.bit32_games is not None \
|
||||
and self.mac_games is not None \
|
||||
and self.assets is not None \
|
||||
and self.no_asset_games is not None
|
||||
and self.no_asset_games is not None \
|
||||
and self.saves is not None
|
||||
|
||||
|
||||
class Signals(QObject):
|
||||
|
|
Loading…
Reference in a new issue