1
0
Fork 0
mirror of synced 2024-06-03 03:04:42 +12:00

Merge pull request #60 from Dummerle/optimize_library_reload

Optimize Library reload: Only reload new widgets. Show updates after imported a game
This commit is contained in:
Dummerle 2021-05-18 10:38:38 +02:00 committed by GitHub
commit 34c6d8b324
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 273 additions and 121 deletions

View file

@ -1,5 +1,5 @@
import os
__version__ = "1.4.0"
__version__ = "1.4.1"
style_path = os.path.join(os.path.dirname(__file__), "styles/")
lang_path = os.path.join(os.path.dirname(__file__), "languages/")

View file

@ -3,8 +3,10 @@ import webbrowser
from PyQt5.QtCore import QSize, pyqtSignal
from PyQt5.QtWidgets import QMenu, QTabWidget, QWidget, QWidgetAction
from qtawesome import icon
from rare.utils import legendary_utils
from custom_legendary.core import LegendaryCore
from rare.components.dialogs.uninstall_dialog import UninstallDialog
from rare.components.tab_utils import TabBar, TabButtonWidget
from rare.components.tabs.account import MiniWidget
from rare.components.tabs.cloud_saves import SyncSaves
@ -63,6 +65,12 @@ class TabWidget(QTabWidget):
# open download tab
self.games_tab.default_widget.game_list.update_game.connect(lambda: self.setCurrentIndex(1))
# uninstall
self.games_tab.game_info.info.uninstall_game.connect(self.uninstall_game)
# imported
self.games_tab.import_widget.update_list.connect(self.game_imported)
if not offline:
# Download finished
self.downloadTab.finished.connect(self.dl_finished)
@ -84,16 +92,38 @@ class TabWidget(QTabWidget):
self.tabBarClicked.connect(lambda x: self.games_tab.layout.setCurrentIndex(0) if x == 0 else None)
self.setIconSize(QSize(25, 25))
def game_imported(self, app_name: str):
igame = self.core.get_installed_game(app_name)
if self.core.get_asset(app_name, True).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.default_widget.game_list.update_list(app_name)
self.games_tab.layout.setCurrentIndex(0)
# Sync game and delete dc rpc
def game_finished(self, app_name):
self.delete_presence.emit()
if self.core.get_game(app_name).supports_cloud_saves:
self.cloud_saves.sync_game(app_name, True)
def uninstall_game(self, app_name):
game = self.core.get_game(app_name)
infos = UninstallDialog(game).get_information()
if infos == 0:
return
legendary_utils.uninstall(game.app_name, self.core, infos)
if app_name in self.downloadTab.update_widgets.keys():
self.downloadTab.update_layout.removeWidget(self.downloadTab.update_widgets[app_name])
self.downloadTab.update_widgets.pop(app_name)
downloads = len(self.downloadTab.dl_queue) + len(self.downloadTab.update_widgets.keys())
self.setTabText(1, "Downloads" + ((" (" + str(downloads) + ")") if downloads != 0 else ""))
self.downloadTab.update_text.setVisible(len(self.downloadTab.update_widgets) == 0)
# Update gamelist and set text of Downlaods to "Downloads"
def dl_finished(self, update_list):
if update_list:
self.games_tab.default_widget.game_list.update_list()
if update_list[0]:
self.games_tab.default_widget.game_list.update_list(update_list[1])
downloads = len(self.downloadTab.dl_queue) + len(self.downloadTab.update_widgets.keys())
self.setTabText(1, "Downloads" + ((" (" + str(downloads) + ")") if downloads != 0 else ""))

View file

@ -20,7 +20,7 @@ logger = getLogger("Download")
class DownloadTab(QWidget):
finished = pyqtSignal(bool)
finished = pyqtSignal(tuple)
thread: QThread
dl_queue = []
@ -75,18 +75,21 @@ class DownloadTab(QWidget):
self.update_text.setVisible(len(updates) == 0)
for igame in updates:
widget = UpdateWidget(core, igame, self)
self.update_layout.addWidget(widget)
self.update_widgets[igame.app_name] = widget
widget.update.connect(self.update_game)
if QSettings().value("auto_update", False, bool):
self.update_game(igame.app_name, True)
widget.update_button.setDisabled(True)
self.add_update(igame)
self.layout.addStretch(1)
self.setLayout(self.layout)
def add_update(self, igame: InstalledGame):
widget = UpdateWidget(self.core, igame, self)
self.update_layout.addWidget(widget)
self.update_widgets[igame.app_name] = widget
widget.update.connect(self.update_game)
if QSettings().value("auto_update", False, bool):
self.update_game(igame.app_name, True)
widget.update_button.setDisabled(True)
def update_dl_queue(self, dl_queue):
self.dl_queue = dl_queue
@ -135,7 +138,7 @@ class DownloadTab(QWidget):
# Information
if not from_update:
if not InstallInfoDialog(dl_size=analysis.dl_size, install_size=analysis.install_size).get_accept():
self.finished.emit(False)
self.finished.emit(False, None)
return
if self.active_game is None:
@ -214,23 +217,25 @@ class DownloadTab(QWidget):
# QMessageBox.information(self, "Info", "Download finished")
logger.info("Download finished: " + self.active_game.app_title)
app_name = self.active_game.app_name
self.active_game = None
if self.dl_queue:
if self.dl_queue[0][1] == self.active_game.app_name:
if self.dl_queue[0][1] == app_name:
self.dl_queue.pop(0)
self.queue_widget.update_queue(self.dl_queue)
if self.active_game.app_name in self.update_widgets.keys():
self.update_widgets[self.active_game.app_name].setVisible(False)
self.update_widgets.pop(self.active_game.app_name)
if app_name in self.update_widgets.keys():
self.update_widgets[app_name].setVisible(False)
self.update_widgets.pop(app_name)
if len(self.update_widgets) == 0:
self.update_text.setVisible(True)
self.active_game = None
for i in self.update_widgets.values():
i.update_button.setDisabled(False)
self.finished.emit(True)
self.finished.emit((True, app_name))
self.reset_infos()
if len(self.dl_queue) != 0:
@ -244,7 +249,7 @@ class DownloadTab(QWidget):
elif text == "stop":
self.reset_infos()
self.active_game = None
self.finished.emit(False)
self.finished.emit((False, None))
if self.dl_queue:
self.start_installation(*self.dl_queue[0])

View file

@ -28,11 +28,11 @@ class GameTab(QWidget):
self.import_widget = ImportWidget(core, self)
self.layout.addWidget(self.import_widget)
self.import_widget.back_button.clicked.connect(lambda: self.layout.setCurrentIndex(0))
self.import_widget.update_list.connect(self.update_list)
# self.import_widget.update_list.connect(self.update_list)
self.setLayout(self.layout)
def update_list(self):
self.default_widget.game_list.update_list(self.default_widget.head_bar.view.isChecked())
def update_list(self, app_name=None):
self.default_widget.game_list.update_list(app_name)
self.layout.setCurrentIndex(0)
def show_info(self, app_name):

View file

@ -58,7 +58,8 @@ class InfoTabs(QTabWidget):
class GameInfo(QScrollArea):
igame: InstalledGame
game: Game
update_list = pyqtSignal()
uninstall_game = pyqtSignal(str)
update_list = pyqtSignal(str)
verify_game = pyqtSignal(str)
verify_threads = {}
@ -115,12 +116,8 @@ class GameInfo(QScrollArea):
self.setWidget(self.widget)
def uninstall(self):
infos = UninstallDialog(self.game).get_information()
if infos == 0:
print("Cancel Uninstall")
return
legendary_utils.uninstall(self.game.app_name, self.core, infos)
self.update_list.emit()
self.uninstall_game.emit(self.game.app_name)
self.update_list.emit(self.game.app_name)
def repair(self):
repair_file = os.path.join(self.core.lgd.get_tmp_path(), f'{self.game.app_name}.repair')

View file

@ -4,9 +4,10 @@ from logging import getLogger
import psutil
from PyQt5.QtCore import Qt, pyqtSignal, QSettings, QTimer
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import *
from PyQt5.QtWidgets import QScrollArea, QWidget, QLabel, QVBoxLayout, QStackedWidget
from custom_legendary.core import LegendaryCore
from rare.components.tabs.games.game_widgets.base_installed_widget import BaseInstalledWidget
from rare.components.tabs.games.game_widgets.installed_icon_widget import GameWidgetInstalled
from rare.components.tabs.games.game_widgets.installed_list_widget import InstalledListWidget
from rare.components.tabs.games.game_widgets.uninstalled_icon_widget import IconWidgetUninstalled
@ -62,7 +63,7 @@ class GameList(QStackedWidget):
self.list_layout = QVBoxLayout()
self.list_layout.addWidget(QLabel(self.info_text))
IMAGE_DIR = self.settings.value("img_dir", os.path.expanduser("~/.cache/rare/images"), str)
self.IMAGE_DIR = self.settings.value("img_dir", os.path.expanduser("~/.cache/rare/images"), str)
self.updates = []
self.widgets = {}
@ -72,85 +73,24 @@ class GameList(QStackedWidget):
# Installed Games
for igame in self.installed:
if os.path.exists(f"{IMAGE_DIR}/{igame.app_name}/FinalArt.png"):
pixmap = QPixmap(f"{IMAGE_DIR}/{igame.app_name}/FinalArt.png")
elif os.path.exists(f"{IMAGE_DIR}/{igame.app_name}/DieselGameBoxTall.png"):
pixmap = QPixmap(f"{IMAGE_DIR}/{igame.app_name}/DieselGameBoxTall.png")
elif os.path.exists(f"{IMAGE_DIR}/{igame.app_name}/DieselGameBoxLogo.png"):
pixmap = QPixmap(f"{IMAGE_DIR}/{igame.app_name}/DieselGameBoxLogo.png")
else:
logger.warning(f"No Image found: {igame.title}")
pixmap = None
if pixmap.isNull():
logger.info(igame.title + " has a corrupt image.")
download_image(igame, force=True)
pixmap = QPixmap(f"{IMAGE_DIR}/{igame.app_name}/DieselGameBoxTall.png")
icon_widget = GameWidgetInstalled(igame, self.core, pixmap, self.offline)
icon_widget, list_widget = self.add_installed_widget(igame)
self.icon_layout.addWidget(icon_widget)
list_widget = InstalledListWidget(igame, self.core, pixmap, self.offline)
self.list_layout.addWidget(list_widget)
icon_widget.show_info.connect(self.show_game_info.emit)
list_widget.show_info.connect(self.show_game_info.emit)
icon_widget.launch_signal.connect(self.launch)
icon_widget.finish_signal.connect(self.finished)
icon_widget.update_list.connect(lambda: self.update_list(self.settings.value("icon_view", True, bool)))
list_widget.launch_signal.connect(self.launch)
list_widget.finish_signal.connect(self.finished)
list_widget.update_list.connect(lambda: self.update_list(self.settings.value("icon_view", True, bool)))
if icon_widget.update_available:
self.updates.append(igame)
self.widgets[igame.app_name] = (icon_widget, list_widget)
active, pid = self.check_for_active_game(igame)
if active:
# Only one game works: Workaround for Satisfactory EA and Exp.
self.launch(igame.app_name)
icon_widget.game_running = True
list_widget.game_running = True
self.active_game = (igame.app_name, pid)
self.timer = QTimer()
self.timer.timeout.connect(self.is_finished)
self.timer.start(10000)
self.uninstalled_games = []
self.uninstalled_names = []
installed = [i.app_name for i in self.core.get_installed_list()]
# get Uninstalled games
games, self.dlcs = self.core.get_game_and_dlc_list()
for game in sorted(games, key=lambda x: x.app_title):
if not game.app_name in installed:
self.uninstalled_games.append(game)
self.uninstalled_names.append(game)
# add uninstalled games
for igame in self.uninstalled_games:
if os.path.exists(f"{IMAGE_DIR}/{igame.app_name}/UninstalledArt.png"):
pixmap = QPixmap(f"{IMAGE_DIR}/{igame.app_name}/UninstalledArt.png")
if pixmap.isNull():
logger.info(igame.app_title + " has a corrupt image.")
download_image(igame, force=True)
pixmap = QPixmap(f"{IMAGE_DIR}/{igame.app_name}/UninstalledArt.png")
else:
logger.warning(f"No Image found: {igame.app_title}")
download_image(igame, force=True)
pixmap = QPixmap(f"{IMAGE_DIR}/{igame.app_name}/UninstalledArt.png")
icon_widget = IconWidgetUninstalled(igame, self.core, pixmap)
icon_widget.install_game.connect(self.install)
list_widget = ListWidgetUninstalled(self.core, igame, pixmap)
list_widget.install_game.connect(self.install)
for game in self.uninstalled_names:
icon_widget, list_widget = self.add_uninstalled_widget(game)
self.icon_layout.addWidget(icon_widget)
self.list_layout.addWidget(list_widget)
self.widgets[igame.app_name] = (icon_widget, list_widget)
self.icon_parent_layout.addLayout(self.icon_layout)
self.icon_parent_layout.addStretch(1)
self.list_layout.addStretch(1)
@ -169,6 +109,79 @@ class GameList(QStackedWidget):
if filter_games := self.settings.value("filter", "", str):
self.filter(filter_games)
def add_uninstalled_widget(self, game):
if os.path.exists(f"{self.IMAGE_DIR}/{game.app_name}/UninstalledArt.png"):
pixmap = QPixmap(f"{self.IMAGE_DIR}/{game.app_name}/UninstalledArt.png")
if pixmap.isNull():
logger.info(game.app_title + " has a corrupt image.")
download_image(game, force=True)
pixmap = QPixmap(f"{self.IMAGE_DIR}/{game.app_name}/UninstalledArt.png")
else:
logger.warning(f"No Image found: {game.app_title}")
download_image(game, force=True)
pixmap = QPixmap(f"{self.IMAGE_DIR}/{game.app_name}/UninstalledArt.png")
icon_widget = IconWidgetUninstalled(game, self.core, pixmap)
icon_widget.install_game.connect(self.install)
list_widget = ListWidgetUninstalled(self.core, game, pixmap)
list_widget.install_game.connect(self.install)
self.widgets[game.app_name] = (icon_widget, list_widget)
return icon_widget, list_widget
def add_installed_widget(self, igame):
if os.path.exists(f"{self.IMAGE_DIR}/{igame.app_name}/FinalArt.png"):
pixmap = QPixmap(f"{self.IMAGE_DIR}/{igame.app_name}/FinalArt.png")
elif os.path.exists(f"{self.IMAGE_DIR}/{igame.app_name}/DieselGameBoxTall.png"):
pixmap = QPixmap(f"{self.IMAGE_DIR}/{igame.app_name}/DieselGameBoxTall.png")
elif os.path.exists(f"{self.IMAGE_DIR}/{igame.app_name}/DieselGameBoxLogo.png"):
pixmap = QPixmap(f"{self.IMAGE_DIR}/{igame.app_name}/DieselGameBoxLogo.png")
else:
logger.warning(f"No Image found: {igame.title}")
pixmap = None
if pixmap.isNull():
logger.info(igame.title + " has a corrupt image.")
download_image(igame, force=True)
pixmap = QPixmap(f"{self.IMAGE_DIR}/{igame.app_name}/DieselGameBoxTall.png")
icon_widget = GameWidgetInstalled(igame, self.core, pixmap, self.offline)
# self.icon_layout.addWidget(icon_widget)
list_widget = InstalledListWidget(igame, self.core, pixmap, self.offline)
# self.list_layout.addWidget(list_widget)
self.widgets[igame.app_name] = (icon_widget, list_widget)
icon_widget.show_info.connect(self.show_game_info.emit)
list_widget.show_info.connect(self.show_game_info.emit)
icon_widget.launch_signal.connect(self.launch)
icon_widget.finish_signal.connect(self.finished)
icon_widget.update_list.connect(self.update_list)
list_widget.launch_signal.connect(self.launch)
list_widget.finish_signal.connect(self.finished)
list_widget.update_list.connect(self.update_list)
if icon_widget.update_available:
self.updates.append(igame)
active, pid = self.check_for_active_game(igame)
if active:
# Only one game works: Workaround for Satisfactory EA and Exp.
self.launch(igame.app_name)
icon_widget.game_running = True
list_widget.game_running = True
self.active_game = (igame.app_name, pid)
self.timer = QTimer()
self.timer.timeout.connect(self.is_finished)
self.timer.start(10000)
return icon_widget, list_widget
def is_finished(self):
if psutil.pid_exists(self.active_game[1]):
self.timer.start(10000)
@ -252,25 +265,132 @@ class GameList(QStackedWidget):
w.setVisible(True)
self.settings.setValue("filter", filter)
def update_list(self, icon_view=True):
self.settings.setValue("icon_view", icon_view)
def update_list(self, app_name=None):
# self.settings.setValue("icon_view", icon_view)
if app_name:
if widgets := self.widgets.get(app_name):
uninstalled_games = []
installed = [i.app_name for i in self.core.get_installed_list()]
# get Uninstalled games
games = self.core.get_game_list(True)
for game in sorted(games, key=lambda x: x.app_title):
if not game.app_name in installed:
uninstalled_games.append(game.app_name)
# from update
if self.core.is_installed(widgets[0].game.app_name) and isinstance(widgets[0], BaseInstalledWidget):
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 = ""
# new installed
elif self.core.is_installed(widgets[0].game.app_name) and not isinstance(widgets[0], BaseInstalledWidget):
self.widgets.pop(widgets[0].game.app_name)
# get new uninstalled/ installed games that changed
new_installed_games = list(set(installed) - set([i.app_name for i in self.installed]))
new_uninstalled_games = list(set(uninstalled_games) - set([i.app_name for i in self.uninstalled_games]))
# QWidget().setLayout(self.icon_layout)
icon_layout = FlowLayout()
# QWidget().setLayout(self.list_layout)
list_layout = QVBoxLayout()
igame = self.core.get_installed_game(app_name)
self.add_installed_widget(igame)
for igame in sorted(self.core.get_installed_list(), key=lambda x: x.title):
i_widget, l_widget = self.widgets[igame.app_name]
icon_layout.addWidget(i_widget)
list_layout.addWidget(l_widget)
self.uninstalled_names = []
installed_names = [i.app_name for i in self.core.get_installed_list()]
# get Uninstalled games
games, self.dlcs = self.core.get_game_and_dlc_list()
for game in sorted(games, key=lambda x: x.app_title):
if not game.app_name in installed_names:
self.uninstalled_names.append(game)
for game in self.uninstalled_names:
i_widget, list_widget = self.widgets[game.app_name]
icon_layout.addWidget(i_widget)
list_layout.addWidget(list_widget)
QWidget().setLayout(self.icon_layout)
QWidget().setLayout(self.list_layout)
self.icon_widget = QWidget()
self.list_widget = QWidget()
self.icon_widget.setLayout(icon_layout)
self.list_widget.setLayout(list_layout)
self.list_scrollarea.setWidget(QWidget())
self.icon_scrollarea.setWidget(QWidget())
self.icon_scrollarea.setWidget(self.icon_widget)
self.list_scrollarea.setWidget(self.list_widget)
self.icon_layout = icon_layout
self.list_layout = list_layout
self.icon_widget.setLayout(self.icon_layout)
self.list_widget.setLayout(self.list_layout)
self.update()
# uninstalled
elif not self.core.is_installed(widgets[0].game.app_name) and isinstance(widgets[0], BaseInstalledWidget):
self.list_layout.removeWidget(widgets[1])
self.icon_layout.removeWidget(widgets[0])
self.widgets.pop(app_name)
game = self.core.get_game(app_name, True)
self.add_uninstalled_widget(game)
self.icon_layout.addWidget(self.widgets[app_name][0])
self.list_layout.addWidget(self.widgets[app_name][1])
else:
installed_names = [i.app_name for i in self.core.get_installed_list()]
# get Uninstalled games
uninstalled_games = []
games = self.core.get_game_list(True)
for game in sorted(games, key=lambda x: x.app_title):
if not game.app_name in installed_names:
uninstalled_games.append(game.app_name)
new_installed_games = list(set(installed_names) - set([i.app_name for i in self.installed]))
new_uninstalled_games = list(set(uninstalled_games) - set([i.app_name for i in self.uninstalled_names]))
if (not new_uninstalled_games) and (not new_installed_games):
return
if new_installed_games:
for name in new_installed_games:
self.icon_layout.removeWidget(self.widgets[app_name][0])
self.list_layout.removeWidget(self.widgets[app_name][1])
self.widgets.pop(name)
igame = self.core.get_installed_game(name)
self.add_installed_widget(igame)
for name in new_uninstalled_games:
self.icon_layout.removeWidget(self.widgets[app_name][0])
self.list_layout.removeWidget(self.widgets[app_name][1])
self.widgets.pop(name)
game = self.core.get_game(name, True)
self.add_uninstalled_widget(game)
for igame in sorted(self.core.get_installed_list(), key=lambda x: x.title):
i_widget, list_widget = self.widgets[igame.app_name]
self.icon_layout.addWidget(i_widget)
self.list_layout.addWidget(list_widget)
# get Uninstalled games
games, self.dlcs = self.core.get_game_and_dlc_list()
for game in sorted(games, key=lambda x: x.app_title):
if not game.app_name in installed_names:
self.uninstalled_names.append(game)
for name in uninstalled_games:
i_widget, list_widget = self.widgets[name]
self.icon_layout.addWidget(i_widget)
self.list_layout.addWidget(list_widget)
if not new_uninstalled_games and not new_installed_games:
return
self.removeWidget(self.icon_scrollarea)
self.removeWidget(self.list_scrollarea)
self.init_ui(icon_view)
self.update()

View file

@ -142,4 +142,4 @@ class BaseInstalledWidget(QGroupBox):
print("Cancel Uninstall")
return
legendary_utils.uninstall(self.game.app_name, self.core, infos)
self.update_list.emit()
self.update_list.emit(self.game.app_name)

View file

@ -14,7 +14,7 @@ logger = getLogger("GameWidgetInstalled")
class GameWidgetInstalled(BaseInstalledWidget):
update_list = pyqtSignal()
update_list = pyqtSignal(str)
show_info = pyqtSignal(str)
update_game = pyqtSignal()

View file

@ -16,7 +16,7 @@ logger = getLogger("Import")
class ImportWidget(QWidget):
update_list = pyqtSignal()
update_list = pyqtSignal(str)
def __init__(self, core: LegendaryCore, parent):
super(ImportWidget, self).__init__(parent=parent)
@ -125,7 +125,7 @@ class ImportWidget(QWidget):
self.core.get_installed_game(app_name).title))
self.app_name_input.setText("")
self.update_list.emit()
self.update_list.emit(app_name)
else:
logger.warning("Failed to import" + app_name)
self.info_label.setText(self.tr("Failed to import {}").format(app_name))
@ -169,6 +169,6 @@ class ImportWidget(QWidget):
if imported > 0:
QMessageBox.information(self, "Imported Games",
self.tr("Successfully imported {} Games. Reloading Library").format(imported))
self.update_list.emit()
self.update_list.emit("")
else:
QMessageBox.information(self, "Imported Games", self.tr("No Games were found"))