1
0
Fork 0
mirror of synced 2024-05-23 14:00:05 +12:00
Rare/rare/components/tabs/games/game_info/game_dlc.py
2024-02-21 13:30:41 +02:00

197 lines
7.8 KiB
Python

from typing import Optional, List
from PyQt5.QtCore import Qt, pyqtSlot, pyqtSignal
from PyQt5.QtGui import QShowEvent
from PyQt5.QtWidgets import QFrame, QMessageBox, QToolBox
from rare.models.game import RareGame
from rare.shared import LegendaryCoreSingleton, GlobalSignalsSingleton
from rare.ui.components.tabs.games.game_info.game_dlc import Ui_GameDlc
from rare.ui.components.tabs.games.game_info.game_dlc_widget import Ui_GameDlcWidget
from rare.widgets.image_widget import ImageWidget, ImageSize
from rare.widgets.side_tab import SideTabContents
from rare.utils.misc import widget_object_name, qta_icon
class GameDlcWidget(QFrame):
def __init__(self, rgame: RareGame, rdlc: RareGame, parent=None):
super(GameDlcWidget, self).__init__(parent=parent)
self.ui = Ui_GameDlcWidget()
self.ui.setupUi(self)
self.setObjectName(widget_object_name(self, rdlc.app_name))
self.rgame = rgame
self.rdlc = rdlc
self.image = ImageWidget(self)
self.image.setFixedSize(ImageSize.Icon)
self.ui.dlc_layout.insertWidget(0, self.image)
self.ui.dlc_name.setText(rdlc.app_title)
self.ui.version.setText(rdlc.version)
self.ui.app_name.setText(rdlc.app_name)
self.image.setPixmap(rdlc.pixmap)
self.__update()
rdlc.signals.widget.update.connect(self.__update)
@pyqtSlot()
def __update(self):
self.ui.action_button.setEnabled(self.rdlc.is_idle)
self.image.setPixmap(self.rdlc.pixmap)
def showEvent(self, a0: QShowEvent) -> None:
if a0.spontaneous():
return super().showEvent(a0)
if self.rdlc.pixmap.isNull():
self.rdlc.load_pixmap()
super().showEvent(a0)
class InstalledGameDlcWidget(GameDlcWidget):
uninstalled = pyqtSignal(RareGame)
def __init__(self, rgame: RareGame, rdlc: RareGame, parent=None):
super(InstalledGameDlcWidget, self).__init__(rgame=rgame, rdlc=rdlc, parent=parent)
# lk: set object names for CSS properties
self.ui.action_button.setObjectName("UninstallButton")
self.ui.action_button.clicked.connect(self.uninstall_dlc)
self.ui.action_button.setText(self.tr("Uninstall DLC"))
self.ui.action_button.setIcon(qta_icon("ri.uninstall-line"))
# lk: don't reference `self.rdlc` here because the object has been deleted
rdlc.signals.game.uninstalled.connect(self.__uninstalled)
@pyqtSlot()
def __uninstalled(self):
self.uninstalled.emit(self.rdlc)
def uninstall_dlc(self):
self.rdlc.uninstall()
class AvailableGameDlcWidget(GameDlcWidget):
installed = pyqtSignal(RareGame)
def __init__(self, rgame: RareGame, rdlc: RareGame, parent=None):
super(AvailableGameDlcWidget, self).__init__(rgame=rgame, rdlc=rdlc, parent=parent)
# lk: set object names for CSS properties
self.ui.action_button.setObjectName("InstallButton")
self.ui.action_button.clicked.connect(self.install_dlc)
self.ui.action_button.setText(self.tr("Install DLC"))
self.ui.action_button.setIcon(qta_icon("ri.install-line"))
# lk: don't reference `self.rdlc` here because the object has been deleted
rdlc.signals.game.installed.connect(self.__installed)
@pyqtSlot()
def __installed(self):
self.installed.emit(self.rdlc)
def install_dlc(self):
if not self.rgame.is_installed:
QMessageBox.warning(
self,
self.tr("Error"),
self.tr("Base Game is not installed. Please install {} first").format(self.rgame.app_title),
)
return
self.rdlc.install()
class GameDlc(QToolBox, SideTabContents):
def __init__(self, parent=None):
super(GameDlc, self).__init__(parent=parent)
self.implements_scrollarea = True
self.ui = Ui_GameDlc()
self.ui.setupUi(self)
self.core = LegendaryCoreSingleton()
self.signals = GlobalSignalsSingleton()
self.rgame: Optional[RareGame] = None
def list_installed(self) -> List[InstalledGameDlcWidget]:
return self.ui.installed_dlc_container.findChildren(InstalledGameDlcWidget, options=Qt.FindDirectChildrenOnly)
def list_available(self) -> List[AvailableGameDlcWidget]:
return self.ui.available_dlc_container.findChildren(AvailableGameDlcWidget, options=Qt.FindDirectChildrenOnly)
def get_installed(self, app_name: str) -> Optional[InstalledGameDlcWidget]:
return self.ui.installed_dlc_container.findChild(
InstalledGameDlcWidget,
name=widget_object_name(InstalledGameDlcWidget, app_name),
options=Qt.FindDirectChildrenOnly
)
def get_available(self, app_name: str) -> Optional[AvailableGameDlcWidget]:
return self.ui.available_dlc_container.findChild(
AvailableGameDlcWidget,
name=widget_object_name(AvailableGameDlcWidget, app_name),
options=Qt.FindDirectChildrenOnly
)
def update_installed_page(self):
have_installed = bool(self.list_installed())
self.ui.installed_dlc_label.setVisible(not have_installed)
self.ui.installed_dlc_container.setVisible(have_installed)
if not have_installed:
self.setCurrentWidget(self.ui.available_dlc_page)
def update_available_page(self):
have_available = bool(self.list_available())
self.ui.available_dlc_label.setVisible(not have_available)
self.ui.available_dlc_container.setVisible(have_available)
if not have_available:
self.setCurrentWidget(self.ui.installed_dlc_page)
def append_installed(self, rdlc: RareGame):
self.ui.installed_dlc_label.setVisible(False)
self.ui.installed_dlc_container.setVisible(True)
a_widget: AvailableGameDlcWidget = self.get_available(rdlc.app_name)
if a_widget is not None:
self.ui.available_dlc_container.layout().removeWidget(a_widget)
a_widget.deleteLater()
i_widget: InstalledGameDlcWidget = InstalledGameDlcWidget(
self.rgame, rdlc, self.ui.installed_dlc_container
)
i_widget.destroyed.connect(self.update_installed_page)
i_widget.uninstalled.connect(self.append_available)
self.ui.installed_dlc_container.layout().addWidget(i_widget)
def append_available(self, rdlc: RareGame):
self.ui.available_dlc_label.setVisible(False)
self.ui.available_dlc_container.setVisible(True)
i_widget: InstalledGameDlcWidget = self.get_installed(rdlc.app_name)
if i_widget is not None:
self.ui.available_dlc_container.layout().removeWidget(i_widget)
i_widget.deleteLater()
a_widget: AvailableGameDlcWidget = AvailableGameDlcWidget(
self.rgame, rdlc, self.ui.available_dlc_container
)
a_widget.destroyed.connect(self.update_available_page)
a_widget.installed.connect(self.append_installed)
self.ui.available_dlc_container.layout().addWidget(a_widget)
def update_dlcs(self, rgame: RareGame):
self.rgame = rgame
self.set_title.emit(self.rgame.app_title)
for i_widget in self.list_installed():
self.ui.installed_dlc_container.layout().removeWidget(i_widget)
i_widget.deleteLater()
for a_widget in self.list_available():
self.ui.available_dlc_container.layout().removeWidget(a_widget)
a_widget.deleteLater()
for dlc in sorted(self.rgame.owned_dlcs, key=lambda x: x.app_title):
if dlc.is_installed:
self.append_installed(rdlc=dlc)
else:
self.append_available(rdlc=dlc)
if not self.list_available():
self.setCurrentWidget(self.ui.installed_dlc_page)
if not self.list_installed():
self.setCurrentWidget(self.ui.available_dlc_page)