1
0
Fork 0
mirror of synced 2024-06-21 12:00:25 +12:00

Much optimization

- updating text in installed widgets
- move tab_widget.py to __init__.py
- errors at launching are now in a popup
- remove old sync widget
This commit is contained in:
Dummerle 2021-11-02 21:57:19 +01:00
parent 65f85f9b3d
commit 0e88d3965f
No known key found for this signature in database
GPG key ID: AB68CC59CA39F2F1
11 changed files with 204 additions and 541 deletions

View file

@ -6,7 +6,7 @@ from PyQt5.QtGui import QCloseEvent
from PyQt5.QtWidgets import QMainWindow, QMessageBox, QApplication
from rare import data_dir, shared
from rare.components.tabs.tab_widget import TabWidget
from rare.components.tabs import TabWidget
from rare.utils.rpc import DiscordRPC
logger = getLogger("Window")

View file

@ -0,0 +1,110 @@
from PyQt5.QtCore import QSize, pyqtSignal
from PyQt5.QtWidgets import QMenu, QTabWidget, QWidget, QWidgetAction, QShortcut
from qtawesome import icon
from rare import shared
from rare.components.tabs.account import MiniWidget
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
class TabWidget(QTabWidget):
delete_presence = pyqtSignal()
def __init__(self, parent):
super(TabWidget, self).__init__(parent=parent)
disabled_tab = 3 if not shared.args.offline else 1
self.core = shared.core
self.signals = shared.signals
self.setTabBar(TabBar(disabled_tab))
# Generate Tabs
self.games_tab = GamesTab()
self.addTab(self.games_tab, self.tr("Games"))
if not shared.args.offline:
# updates = self.games_tab.default_widget.game_list.updates
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.store = Shop(self.core)
self.addTab(self.store, self.tr("Store (Beta)"))
self.settings = SettingsTab(self)
if shared.args.debug:
self.settings.addTab(DebugSettings(), "Debug")
# Space Tab
self.addTab(QWidget(), "")
self.setTabEnabled(disabled_tab, False)
# Button
self.account = QWidget()
self.addTab(self.account, "")
self.setTabEnabled(disabled_tab + 1, False)
self.mini_widget = MiniWidget()
account_action = QWidgetAction(self)
account_action.setDefaultWidget(self.mini_widget)
account_button = TabButtonWidget('mdi.account-circle', 'Account')
account_button.setMenu(QMenu())
account_button.menu().addAction(account_action)
self.tabBar().setTabButton(disabled_tab + 1, self.tabBar().RightSide, account_button)
self.addTab(self.settings, icon("fa.gear"),
"(!)" if self.settings.about.update_available else "")
# Signals
# set current index
self.signals.set_main_tab_index.connect(self.setCurrentIndex)
# update dl tab text
self.signals.update_download_tab_text.connect(self.update_dl_tab_text)
# Open game list on click on Games tab button
self.tabBarClicked.connect(self.mouse_clicked)
self.setIconSize(QSize(25, 25))
# shortcuts
QShortcut("Alt+1", self).activated.connect(lambda: self.setCurrentIndex(0))
QShortcut("Alt+2", self).activated.connect(lambda: self.setCurrentIndex(1))
QShortcut("Alt+3", self).activated.connect(lambda: self.setCurrentIndex(2))
QShortcut("Alt+4", self).activated.connect(lambda: self.setCurrentIndex(5))
def update_dl_tab_text(self):
num_downloads = len(set([i.options.app_name for i in self.downloadTab.dl_queue] + [i for i in
self.downloadTab.update_widgets.keys()]))
if num_downloads != 0:
self.setTabText(1, f"Downloads ({num_downloads})")
else:
self.setTabText(1, "Downloads")
def mouse_clicked(self, tab_num):
if tab_num == 0:
self.games_tab.layout().setCurrentIndex(0)
if not shared.args.offline and tab_num == 3:
self.store.load()
def game_imported(self, app_name: str):
igame = self.core.get_installed_game(app_name)
if self.core.get_asset(app_name, False).build_version != igame.version:
self.downloadTab.add_update(igame)
downloads = len(self.downloadTab.dl_queue) + len(self.downloadTab.update_widgets.keys())
self.setTabText(1, "Downloads" + ((" (" + str(downloads) + ")") if downloads != 0 else ""))
self.games_tab.update_list(app_name)
self.games_tab.setCurrentIndex(0)
def resizeEvent(self, event):
self.tabBar().setMinimumWidth(self.width())
super(TabWidget, self).resizeEvent(event)
# Remove text "sync game"
def finished_sync(self, app_name):
if self.core.is_installed(app_name):
self.games_tab.widgets[app_name][0].info_text = ""
self.games_tab.widgets[app_name][0].info_label.setText("")
self.games_tab.widgets[app_name][1].info_label.setText("")

View file

@ -1,156 +0,0 @@
from logging import getLogger
from PyQt5.QtCore import QThread, pyqtSignal, Qt
from PyQt5.QtWidgets import QScrollArea, QWidget, QVBoxLayout, QLabel, QPushButton, QMessageBox
from legendary.core import LegendaryCore
from legendary.models.game import SaveGameStatus
from rare import shared
from rare.components.dialogs.path_input_dialog import PathInputDialog
from rare.components.tabs.cloud_saves.sync_widget import SyncWidget
from rare.utils.extra_widgets import WaitingSpinner
logger = getLogger("Sync Saves")
class LoadThread(QThread):
signal = pyqtSignal(list)
def __init__(self, core: LegendaryCore):
super(LoadThread, self).__init__()
self.core = core
def run(self) -> None:
saves = self.core.get_save_games()
self.signal.emit(saves)
class SyncSaves(QScrollArea):
finished = pyqtSignal(str)
def __init__(self):
super(SyncSaves, self).__init__()
self.core = shared.core
self.signals = shared.signals
self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
self.load_saves()
def load_saves(self, app_name=None, auto=False):
self.widget = QWidget()
layout = QVBoxLayout()
layout.addWidget(WaitingSpinner())
layout.addWidget(QLabel("<h4>Loading Cloud Saves</h4>"))
layout.addStretch()
self.widget.setLayout(layout)
self.setWidget(self.widget)
self.start_thread = LoadThread(self.core)
self.start_thread.signal.connect(lambda x: self.setup_ui(x, app_name, auto))
self.start_thread.start()
self.igames = self.core.get_installed_list()
def setup_ui(self, saves: list, app_name, auto=False):
self.start_thread.disconnect()
self.main_layout = QVBoxLayout()
self.title = QLabel(
f"<h1>" + self.tr("Cloud Saves") + "</h1>\n" + self.tr("Found Saves for folowing Games"))
self.main_layout.addWidget(self.title)
saves_games = []
for i in saves:
if not i.app_name in saves_games and self.core.is_installed(i.app_name):
saves_games.append(i.app_name)
if len(saves_games) == 0:
# QMessageBox.information(self.tr("No Games Found"), self.tr("Your games don't support cloud save"))
self.title.setText(
f"<h1>" + self.tr("Cloud Saves") + "</h1>\n" + self.tr("Your games does not support Cloud Saves"))
self.setWidget(self.title)
return
self.sync_all_button = QPushButton(self.tr("Sync all games"))
self.sync_all_button.clicked.connect(self.sync_all)
self.main_layout.addWidget(self.sync_all_button)
latest_save = {}
for i in sorted(saves, key=lambda a: a.datetime):
latest_save[i.app_name] = i
logger.info(f'Got {len(latest_save)} remote save game(s)')
self.widgets = []
for igame in self.igames:
game = self.core.get_game(igame.app_name)
if not game.supports_cloud_saves:
continue
if latest_save.get(igame.app_name):
sync_widget = SyncWidget(igame, latest_save[igame.app_name])
else:
continue
sync_widget.reload.connect(self.reload)
self.main_layout.addWidget(sync_widget)
self.widgets.append(sync_widget)
self.widget = QWidget()
self.main_layout.addStretch(1)
self.widget.setLayout(self.main_layout)
self.setWidgetResizable(True)
self.setWidget(self.widget)
if auto:
self.save(app_name, True)
def reload(self, app_name, auto=False):
self.finished.emit(app_name)
self.setWidget(QWidget())
self.load_saves(auto)
def sync_game(self, app_name, from_game_finish_auto=True):
self.setWidget(QWidget())
self.load_saves(app_name, from_game_finish_auto)
def save(self, app_name, from_game_finish_auto=True):
for w in self.widgets:
if w.igame.app_name == app_name:
widget = w
break
else:
logger.warning("An Error occurred. Game does not support cloud saves")
return
if widget.res == SaveGameStatus.SAME_AGE:
logger.info("Game is up to date")
elif widget.res == SaveGameStatus.LOCAL_NEWER:
widget.upload()
elif widget.res == SaveGameStatus.REMOTE_NEWER:
if from_game_finish_auto:
if QMessageBox.question(self, "Really", self.tr("You finished playing game, but Remote game is newer. "
"Do you want to download anyway? This could remove "
"your game progress. Please check your save path or "
"make a backup"),
QMessageBox.Yes | QMessageBox.No, QMessageBox.No) == QMessageBox.Yes:
widget.download()
else:
logger.info("Cancel Download")
self.finished.emit(app_name)
def sync_all(self):
logger.info("Sync all Games")
for w in self.widgets:
if not w.igame.save_path:
save_path = self.core.get_save_path(w.igame.app_name)
if '%' in save_path or '{' in save_path:
self.logger.info_label("Could not find save_path")
save_path = PathInputDialog(self.tr("Found no savepath"),
self.tr("No save path was found. Please select path or skip"))
if save_path == "":
continue
else:
w.igame.save_path = save_path
if w.res == SaveGameStatus.SAME_AGE:
continue
if w.res == SaveGameStatus.REMOTE_NEWER:
logger.info("Download")
w.download()
elif w.res == SaveGameStatus.LOCAL_NEWER:
logger.info("Upload")
w.upload()

View file

@ -1,231 +0,0 @@
import os
from logging import getLogger
from PyQt5.QtCore import QThread, pyqtSignal, Qt, QSettings
from PyQt5.QtWidgets import QVBoxLayout, QPushButton, QHBoxLayout, QLabel, QGroupBox, QMessageBox
from legendary.core import LegendaryCore
from legendary.models.game import InstalledGame, SaveGameStatus
from rare import shared
from rare.components.dialogs.path_input_dialog import PathInputDialog
logger = getLogger("Sync")
def get_raw_save_path(app_name, core):
game = core.lgd.get_game_meta(app_name)
save_path = game.metadata['customAttributes'].get('CloudSaveFolder', {}).get('value')
return save_path
class _UploadThread(QThread):
signal = pyqtSignal(bool)
def __init__(self, app_name, date_time, save_path, core: LegendaryCore):
super(_UploadThread, self).__init__()
self.core = core
self.app_name = app_name
self.date_time = date_time
self.save_path = save_path
def run(self) -> None:
try:
self.core.upload_save(self.app_name, self.save_path, self.date_time)
self.signal.emit(True)
except Exception as e:
logger.error(e)
self.signal.emit(False)
class _DownloadThread(QThread):
signal = pyqtSignal(bool)
def __init__(self, app_name, latest_save, save_path, core: LegendaryCore):
super(_DownloadThread, self).__init__()
self.core = core
self.app_name = app_name
self.latest_save = latest_save
self.save_path = save_path
def run(self) -> None:
try:
self.core.download_saves(self.app_name, self.latest_save.manifest_name, self.save_path, clean_dir=True)
self.signal.emit(True)
except Exception as e:
logger.error(e)
self.signal.emit(False)
class SyncWidget(QGroupBox):
reload = pyqtSignal(str)
def __init__(self, igame: InstalledGame, save):
super(SyncWidget, self).__init__(igame.title)
self.setObjectName("group")
self.layout = QVBoxLayout()
self.setContentsMargins(10, 20, 10, 20)
self.thr = None
self.core = shared.core
self.save = save
self.logger = getLogger("Sync " + igame.app_name)
self.game = self.core.get_game(igame.app_name)
self.igame = igame
self.has_save_path = True
if not igame.save_path or igame.save_path is None:
try:
save_path = self.core.get_save_path(igame.app_name)
except Exception as e:
self.logger.error(e)
return
if '%' in save_path or '{' in save_path:
# status = self.tr("Path not found")
self.logger.info("Could not find save path")
igame.save_path = ""
else:
igame.save_path = save_path
if not igame.save_path:
igame.save_path = os.path.expanduser(f"~/{igame.app_name}/")
QMessageBox.warning(self, "Savepath error",
self.tr("Please edit save path of game {} manually in Cload saves tab").format(
igame.title))
if igame.save_path and not os.path.exists(igame.save_path):
os.makedirs(igame.save_path)
self.core.lgd.set_installed_game(self.igame.app_name, self.igame)
self.res, (self.dt_local, dt_remote) = self.core.check_savegame_state(igame.save_path, save)
if self.res == SaveGameStatus.NO_SAVE:
self.logger.debug('No cloud or local savegame found.')
return
# game_title = QLabel(f"<h2>{igame.title}</h2>")
if self.dt_local:
local_save_date = QLabel(
self.tr("Local Save date: ") + str(self.dt_local.strftime('%Y-%m-%d %H:%M:%S')))
else:
local_save_date = QLabel(self.tr("No Local Save files"))
if dt_remote:
cloud_save_date = QLabel(self.tr("Cloud save date: ") + str(dt_remote.strftime('%Y-%m-%d %H:%M:%S')))
else:
cloud_save_date = QLabel(self.tr("No Cloud saves"))
if self.res == SaveGameStatus.SAME_AGE:
self.logger.debug(f'Save game for "{igame.title}" is up to date')
status = self.tr("Game is up to date")
self.upload_button = QPushButton(self.tr("Upload anyway"))
self.download_button = QPushButton(self.tr("Download anyway"))
elif self.res == SaveGameStatus.REMOTE_NEWER:
status = self.tr("Cloud save is newer")
self.download_button = QPushButton(self.tr("Download Cloud saves"))
self.download_button.setObjectName("success")
self.upload_button = QPushButton(self.tr("Upload Saves"))
self.logger.debug(f'Cloud save for "{igame.title}" is newer:')
self.logger.debug(f'- Cloud save date: {dt_remote.strftime("%Y-%m-%d %H:%M:%S")}')
if self.dt_local:
self.logger.debug(f'- Local save date: {self.dt_local.strftime("%Y-%m-%d %H:%M:%S")}')
else:
self.logger.debug('- Local save date: N/A')
self.upload_button.setDisabled(True)
self.upload_button.setToolTip("No local save")
elif self.res == SaveGameStatus.LOCAL_NEWER:
status = self.tr("Local save is newer")
self.upload_button = QPushButton(self.tr("Upload saves"))
self.upload_button.setObjectName("success")
self.download_button = QPushButton(self.tr("Download saves"))
self.logger.info(f'Local save for "{igame.title}" is newer')
if dt_remote:
self.logger.debug(f'- Cloud save date: {dt_remote.strftime("%Y-%m-%d %H:%M:%S")}')
else:
self.logger.debug('- Cloud save date: N/A')
self.download_button.setDisabled(True)
self.logger.debug(f'- Local save date: {self.dt_local.strftime("%Y-%m-%d %H:%M:%S")}')
else:
self.logger.error(self.res)
return
self.upload_button.clicked.connect(self.upload)
self.download_button.clicked.connect(self.download)
self.info_text = QLabel(status)
# self.layout.addWidget(game_title)
self.layout.addWidget(local_save_date)
self.layout.addWidget(cloud_save_date)
save_path_layout = QHBoxLayout()
self.raw_path = QLabel("Raw path: " + get_raw_save_path(self.game.app_name, self.core))
self.raw_path.setTextInteractionFlags(Qt.TextSelectableByMouse)
self.layout.addWidget(self.raw_path)
self.save_path_text = QLabel(igame.save_path)
self.save_path_text.setTextInteractionFlags(Qt.TextSelectableByMouse)
self.save_path_text.setWordWrap(True)
self.change_save_path = QPushButton(self.tr("Change path"))
self.change_save_path.setFixedWidth(100)
self.change_save_path.clicked.connect(self.change_path)
save_path_layout.addWidget(self.save_path_text)
save_path_layout.addWidget(self.change_save_path)
self.layout.addLayout(save_path_layout)
self.layout.addWidget(self.info_text)
button_layout = QHBoxLayout()
button_layout.addWidget(self.upload_button)
button_layout.addWidget(self.download_button)
self.layout.addLayout(button_layout)
self.layout.addStretch(1)
self.setLayout(self.layout)
if self.res == SaveGameStatus.REMOTE_NEWER:
settings = QSettings()
if settings.value(f"{igame.app_name}/auto_sync_cloud", False, bool):
self.download()
def change_path(self):
path = PathInputDialog("Select directory", "Select savepath. Warning: Do not change if you are not sure",
self.igame.save_path).get_path()
if path != "":
self.igame.save_path = path
self.core.lgd.set_installed_game(self.igame.app_name, self.igame)
self.save_path_text.setText(self.igame.save_path)
self.reload.emit(self.game.app_name)
def upload(self):
self.logger.info("Uploading Saves for game " + self.igame.title)
self.info_text.setText(self.tr("Uploading..."))
self.upload_button.setDisabled(True)
self.download_button.setDisabled(True)
self.thr = _UploadThread(self.igame.app_name, self.dt_local, self.igame.save_path, self.core)
self.thr.signal.connect(self.uploaded)
self.thr.start()
def uploaded(self, success: bool):
if success:
self.info_text.setText(self.tr("Upload finished"))
else:
self.info_text.setText(self.tr("Upload failed"))
self.upload_button.setDisabled(False)
self.reload.emit(self.game.app_name)
def download(self):
if not os.path.exists(self.igame.save_path):
os.makedirs(self.igame.save_path)
self.upload_button.setDisabled(True)
self.download_button.setDisabled(True)
self.logger.info("Downloading Saves for game " + self.igame.title)
self.info_text.setText(self.tr("Downloading..."))
self.thr = _DownloadThread(self.igame.app_name, self.save, self.igame.save_path, self.core)
self.thr.signal.connect(self.downloaded)
self.thr.start()
def downloaded(self, success: bool):
if success:
self.info_text.setText(self.tr("Download finished"))
self.upload_button.setDisabled(True)
self.download_button.setDisabled(True)
self.download_button.setStyleSheet("QPushButton{background-color: black}")
self.reload.emit(self.game.app_name)
else:
self.info_text.setText("Error while downloading save")
self.download_button.setStyleSheet("QPushButton{background-color: black}")

View file

@ -103,6 +103,8 @@ class GamesTab(QStackedWidget, Ui_GamesTab):
self.signals.installation_finished.connect(lambda x: self.installing_widget.setVisible(False))
self.signals.uninstall_game.connect(self.uninstall_game)
self.game_list_scroll_area.horizontalScrollBar().setDisabled(True)
def installation_started(self, app_name: str):
game = self.core.get_game(app_name, False)
if game.is_dlc:
@ -115,7 +117,9 @@ class GamesTab(QStackedWidget, Ui_GamesTab):
i_widget, l_widget = self.widgets[igame.app_name]
i_widget.igame = igame
l_widget.igame = igame
i_widget.info_text = ""
i_widget.leaveEvent(None)
l_widget.update_text()
def uninstall_game(self, game: Game):
infos = UninstallDialog(game).get_information()
@ -269,11 +273,8 @@ class GamesTab(QStackedWidget, Ui_GamesTab):
igame = self.core.get_installed_game(app_name)
for w in widgets:
w.igame = igame
w.update_available = self.core.get_asset(w.game.app_name,
True).build_version != igame.version
widgets[0].info_label.setText("")
widgets[0].info_text = ""
w.update_available = self.core.get_asset(w.game.app_name, True).build_version != igame.version
widgets[0].leaveEvent(None)
# new installed
elif self.core.is_installed(app_name) and isinstance(widgets[0], BaseUninstalledWidget):
logger.debug("Update Gamelist: New installed " + app_name)
@ -405,3 +406,5 @@ class GamesTab(QStackedWidget, Ui_GamesTab):
else:
self.scroll_widget.layout().replaceWidget(self.icon_view, self.list_view)
self.icon_view.setParent(None)
self.game_list_scroll_area.verticalScrollBar().setValue(0)

View file

@ -123,9 +123,6 @@ class CloudSaveUtils(QObject):
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:

View file

@ -34,7 +34,7 @@ class RunningGameModel:
class GameUtils(QObject):
running_games = dict()
finished = pyqtSignal(str)
finished = pyqtSignal(str, str)
cloud_save_finished = pyqtSignal(str)
launch_queue = dict()
@ -78,12 +78,15 @@ class GameUtils(QObject):
else:
if not game:
logger.error("Game not found")
self.finished.emit(app_name, self.tr("Game not found in available games"))
return
if game.is_dlc:
logger.error("Game is dlc")
self.finished.emit(app_name, self.tr("Game is a DLC. Please launch base game instead"))
return
if not os.path.exists(igame.install_path):
logger.error("Game doesn't exist")
self.finished.emit(app_name, self.tr("Game files of {} do not exist. Please install game"))
return
process = GameProcess(app_name)
@ -96,11 +99,11 @@ class GameUtils(QObject):
try:
latest = self.core.get_asset(app_name, update=True)
except ValueError:
print("Metadata doesn't exist")
return None
self.finished.emit(app_name, self.tr("Metadata doesn't exist"))
return
if latest.build_version != igame.version:
print("Please update game")
return None
self.finished.emit(app_name, self.tr("Please update game"))
return
params: LaunchParameters = self.core.get_launch_parameters(app_name=app_name, offline=offline,
wine_bin=wine_bin, wine_pfx=wine_pfx)
@ -130,6 +133,7 @@ class GameUtils(QObject):
logger.info("Launch Origin Game: ")
if platform.system() == "Windows":
webbrowser.open(origin_uri)
self.finished.emit(app_name, "")
return
wine_pfx = self.core.lgd.config.get(self.game.app_name, 'wine_prefix',
fallback=os.path.expanduser("~/.wine"))
@ -137,9 +141,10 @@ class GameUtils(QObject):
wine_bin = self.core.lgd.config.get(self.game.app_name, 'wine_executable', fallback="/usr/bin/wine")
env = self.core.get_app_environment(self.game.app_name, wine_pfx=wine_pfx)
if not wine_bin or not env.get('WINEPREFIX'):
if not wine_bin or not env.get('WINEPREFIX') and not os.path.exists("/usr/bin/wine"):
logger.error(f'In order to launch Origin correctly you must specify the wine binary and prefix '
f'to use in the configuration file or command line. See the README for details.')
self.finished.emit(app_name, self.tr("No wine executable selected. Please set it in settings"))
return
environment = QProcessEnvironment()
@ -175,7 +180,7 @@ class GameUtils(QObject):
webbrowser.open("https://www.dm.origin.com/download")
self.running_games.pop(app_name)
self.finished.emit(app_name)
self.finished.emit(app_name, "")
if QSettings().value("show_console", False, bool):
self.console.log(f"Game exited with code: {exit_code}")

View file

@ -26,13 +26,29 @@ class BaseInstalledWidget(QGroupBox):
self.core = shared.core
self.game_utils = game_utils
self.game_utils.cloud_save_finished.connect(self.sync_finished)
self.sync_cloud_saves = False
self.syncing_cloud_saves = False
self.texts = {
"needs_verification": self.tr("Please verify game before playing"),
"hover": {
"update_available": self.tr("Start game without version check"),
"launch": self.tr("Launch Game"),
"launch_origin": self.tr("Launch/Link"),
"running": self.tr("Game running")
},
"default": {
"running": self.tr("Game running"),
"syncing": self.tr("Syncing cloud saves"),
"update_available": self.tr("Update available")
}
}
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.igame = None
self.is_origin = True
self.image = QLabel()
@ -129,13 +145,19 @@ class BaseInstalledWidget(QGroupBox):
self.create_start_menu.setText(self.tr("Create Start menu link"))
def launch(self, offline=False, skip_version_check=False):
if self.game.supports_cloud_saves:
self.sync_cloud_saves = True
self.game_utils.launch_game(self.game.app_name, offline=offline, skip_update_check=skip_version_check)
if not self.game_running:
if self.game.supports_cloud_saves:
self.syncing_cloud_saves = True
self.game_utils.prepare_launch(self.game.app_name, offline, skip_version_check)
def sync_finished(self, app_name):
if app_name == self.game.app_name:
self.sync_cloud_saves = False
self.syncing_cloud_saves = False
def sync_game(self):
self.game_utils.cloud_save_utils.sync_before_launch_game(self.game.app_name)
if self.game_utils.cloud_save_utils.sync_before_launch_game(self.game.app_name):
self.syncing_cloud_saves = True
def game_finished(self, app_name, error):
if error:
QMessageBox.warning(self, "Error", error)

View file

@ -21,12 +21,9 @@ class InstalledIconWidget(BaseInstalledWidget):
self.setContextMenuPolicy(Qt.ActionsContextMenu)
self.layout = QVBoxLayout()
self.core = shared.core
self.running = False
self.info_text = ""
if self.update_available:
logger.info("Update available for game: " + self.game.app_name)
self.info_text = self.tr("Update available")
self.layout.addWidget(self.image)
@ -45,9 +42,8 @@ class InstalledIconWidget(BaseInstalledWidget):
self.menu_btn.setIcon(icon("ei.info-circle"))
# self.menu_btn.setObjectName("installed_menu_button")
self.menu_btn.setIconSize(QSize(18, 18))
self.menu_btn.enterEvent = lambda x: self.info_label.setText("Information")
self.menu_btn.leaveEvent = lambda x: self.info_label.setText(
"Please update Game") if self.update_available else self.info_label.setText("Start Game")
self.menu_btn.enterEvent = lambda x: self.info_label.setText(self.tr("Information"))
self.menu_btn.leaveEvent = lambda x: self.enterEvent(None)
# remove Border
self.menu_btn.setObjectName("menu_button")
@ -58,33 +54,37 @@ class InstalledIconWidget(BaseInstalledWidget):
minilayout.addStretch(1)
self.layout.addLayout(minilayout)
self.info_label = QLabel(self.info_text)
self.info_label = QLabel("")
self.leaveEvent(None)
self.info_label.setAutoFillBackground(False)
self.info_label.setObjectName("info_label")
self.layout.addWidget(self.info_label)
if not self.is_origin and self.igame.needs_verification:
self.info_text = self.tr("Game needs verification")
self.info_label.setText(self.info_text)
self.info_label.setText(self.texts["needs_verification"])
self.setLayout(self.layout)
self.setFixedWidth(self.sizeHint().width())
def enterEvent(self, a0: QEvent) -> None:
def enterEvent(self, a0: QEvent = None) -> None:
if self.game_running:
self.info_label.setText(self.tr("Game running"))
self.info_label.setText(self.texts["hover"]["running"])
elif not self.is_origin and self.igame.needs_verification:
self.info_label.setText(self.tr("Please verify game before playing"))
self.info_label.setText(self.texts["hover"]["needs_verification"])
elif self.update_available:
self.info_label.setText(self.tr("Start game without version check"))
self.info_label.setText(self.texts["hover"]["update_available"])
else:
self.info_label.setText(self.tr("Start Game") if not self.is_origin else self.tr("Launch/Link"))
self.info_label.setText(self.texts["hover"]["launch" if not self.is_origin else "launch_origin"])
def leaveEvent(self, a0: QEvent) -> None:
if self.running:
self.info_label.setText(self.tr("Game running"))
def leaveEvent(self, a0: QEvent = None) -> None:
if self.game_running:
self.info_label.setText(self.texts["default"]["running"])
elif self.syncing_cloud_saves:
self.info_label.setText(self.texts["default"]["syncing"])
elif self.update_available:
self.info_label.setText(self.texts["default"]["update_available"])
else:
self.info_label.setText(self.info_text)
self.info_label.setText("")
def mousePressEvent(self, e: QMouseEvent):
# left button
@ -100,9 +100,10 @@ class InstalledIconWidget(BaseInstalledWidget):
elif e.button() == 2:
pass # self.showMenu(e)
def game_finished(self, app_name):
def game_finished(self, app_name, error):
if app_name != self.game.app_name:
return
self.info_text = ""
self.info_label.setText("")
super().game_finished(app_name, error)
self.leaveEvent(None)

View file

@ -32,17 +32,22 @@ class InstalledListWidget(BaseInstalledWidget):
self.layout.addWidget(self.image)
play_icon = icon("ei.play")
self.title_widget = QLabel(f"<h1>{self.game.app_title}</h1>")
self.title_label = QLabel(f"<h1>{self.game.app_title}</h1>")
self.title_label.setWordWrap(True)
self.childLayout.addWidget(self.title_label)
self.app_name_label = QLabel(self.game.app_name)
self.launch_button = QPushButton(play_icon, self.tr("Launch") if not self.is_origin else self.tr("Link/Play"))
self.launch_button.setObjectName("launch_game_button")
self.launch_button.setFixedWidth(120)
self.launch_button.setFixedWidth(150)
self.info = QPushButton("Info")
self.info.clicked.connect(lambda: self.show_info.emit(self.game))
self.info.setFixedWidth(80)
self.childLayout.addWidget(self.title_widget)
self.info_label = QLabel("")
self.childLayout.addWidget(self.info_label)
self.update_text()
self.launch_button.clicked.connect(self.launch)
self.childLayout.addWidget(self.launch_button)
@ -57,15 +62,22 @@ class InstalledListWidget(BaseInstalledWidget):
self.childLayout.addWidget(self.version_label)
self.childLayout.addWidget(self.size_label)
self.info_label = QLabel("")
self.childLayout.addWidget(self.info_label)
# self.childLayout.addWidget(QPushButton("Settings"))
# self.childLayout.addWidget(QPushButton("Uninstall"))
self.childLayout.addStretch(1)
self.layout.addLayout(self.childLayout)
self.layout.addStretch(1)
self.setLayout(self.layout)
def launch(self):
if not self.game_running:
super(InstalledListWidget, self).launch(skip_version_check=self.update_available)
self.game_utils.cloud_save_finished.connect(self.sync_finished)
self.leaveEvent = self.update_text
self.enterEvent = self.update_text
def update_text(self, e=None):
if self.update_available:
self.info_label.setText(self.texts["default"]["update_available"])
elif self.igame and self.igame.needs_verification:
self.info_label.setText(self.texts["needs_verification"])
elif self.syncing_cloud_saves:
self.info_label.setText(self.texts["default"]["syncing"])
else:
self.info_label.setText("")

View file

@ -1,100 +0,0 @@
from PyQt5.QtCore import QSize, pyqtSignal
from PyQt5.QtWidgets import QMenu, QTabWidget, QWidget, QWidgetAction, QShortcut
from qtawesome import icon
from rare import shared
from rare.components.tabs.account import MiniWidget
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
class TabWidget(QTabWidget):
delete_presence = pyqtSignal()
def __init__(self, parent):
super(TabWidget, self).__init__(parent=parent)
disabled_tab = 3 if not shared.args.offline else 1
self.core = shared.core
self.signals = shared.signals
self.setTabBar(TabBar(disabled_tab))
# Generate Tabs
self.games_tab = GamesTab()
self.addTab(self.games_tab, self.tr("Games"))
if not shared.args.offline:
# updates = self.games_tab.default_widget.game_list.updates
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.store = Shop(self.core)
self.addTab(self.store, self.tr("Store (Beta)"))
self.settings = SettingsTab(self)
if shared.args.debug:
self.settings.addTab(DebugSettings(), "Debug")
# Space Tab
self.addTab(QWidget(), "")
self.setTabEnabled(disabled_tab, False)
# Button
self.account = QWidget()
self.addTab(self.account, "")
self.setTabEnabled(disabled_tab + 1, False)
self.mini_widget = MiniWidget()
account_action = QWidgetAction(self)
account_action.setDefaultWidget(self.mini_widget)
account_button = TabButtonWidget('mdi.account-circle', 'Account')
account_button.setMenu(QMenu())
account_button.menu().addAction(account_action)
self.tabBar().setTabButton(disabled_tab + 1, self.tabBar().RightSide, account_button)
self.addTab(self.settings, icon("fa.gear"),
"(!)" if self.settings.about.update_available else "")
# Signals
# set current index
self.signals.set_main_tab_index.connect(self.setCurrentIndex)
# update dl tab text
self.signals.update_download_tab_text.connect(self.update_dl_tab_text)
# Open game list on click on Games tab button
self.tabBarClicked.connect(self.mouse_clicked)
self.setIconSize(QSize(25, 25))
# shortcuts
QShortcut("Alt+1", self).activated.connect(lambda: self.setCurrentIndex(0))
QShortcut("Alt+2", self).activated.connect(lambda: self.setCurrentIndex(1))
QShortcut("Alt+3", self).activated.connect(lambda: self.setCurrentIndex(2))
QShortcut("Alt+4", self).activated.connect(lambda: self.setCurrentIndex(5))
def update_dl_tab_text(self):
num_downloads = len(set([i.options.app_name for i in self.downloadTab.dl_queue] + [i for i in
self.downloadTab.update_widgets.keys()]))
if num_downloads != 0:
self.setTabText(1, f"Downloads ({num_downloads})")
else:
self.setTabText(1, "Downloads")
def mouse_clicked(self, tab_num):
if tab_num == 0:
self.games_tab.layout().setCurrentIndex(0)
if not shared.args.offline and tab_num == 3:
self.store.load()
def resizeEvent(self, event):
self.tabBar().setMinimumWidth(self.width())
super(TabWidget, self).resizeEvent(event)
# Remove text "sync game"
def finished_sync(self, app_name):
if self.core.is_installed(app_name):
self.games_tab.widgets[app_name][0].info_text = ""
self.games_tab.widgets[app_name][0].info_label.setText("")
self.games_tab.widgets[app_name][1].info_label.setText("")