1
0
Fork 0
mirror of synced 2024-07-03 21:51:10 +12:00
Rare/rare/components/tabs/downloads/widgets.py
loathingKernel 523391d166 QueueWidget: Prepare requeued downloads after adding it.
By preparing the download inside the widget, the delay after stopping
the running download and visual feedback of adding the widget is
reduced. The widget will now appear containing the basic information
and will be populated with the information about the download
when it is ready. The widget is disabled in the meantime.

Move `InstallInfoWorker` to `rare.shared.workers` module and
revert it to emitting a `InstallDownloadItem` model only
instead of a `InstallQueueItemModel.`
2023-02-04 17:38:07 +02:00

168 lines
6.7 KiB
Python

from logging import getLogger
from typing import Optional
from PyQt5.QtCore import pyqtSignal, Qt, QThreadPool, pyqtSlot
from PyQt5.QtWidgets import QWidget, QFrame
from legendary.models.downloading import AnalysisResult
from legendary.models.game import Game, InstalledGame
from qtawesome import icon
from rare.models.install import InstallQueueItemModel, InstallOptionsModel, InstallDownloadModel
from rare.shared import RareCore, ImageManagerSingleton
from rare.shared.workers.install_info import InstallInfoWorker
from rare.ui.components.tabs.downloads.download_widget import Ui_DownloadWidget
from rare.ui.components.tabs.downloads.info_widget import Ui_InfoWidget
from rare.utils.misc import get_size, widget_object_name, elide_text
from rare.widgets.image_widget import ImageWidget, ImageSize
logger = getLogger("DownloadWidgets")
class InfoWidget(QWidget):
def __init__(
self,
game: Optional[Game],
igame: Optional[InstalledGame],
analysis: Optional[AnalysisResult] = None,
old_igame: Optional[InstalledGame] = None,
parent=None,
):
super(InfoWidget, self).__init__(parent=parent)
self.ui = Ui_InfoWidget()
self.ui.setupUi(self)
self.image_manager = ImageManagerSingleton()
self.image = ImageWidget(self)
self.image.setFixedSize(ImageSize.Icon)
self.ui.image_layout.addWidget(self.image)
self.ui.info_widget_layout.setAlignment(Qt.AlignTop)
if game and igame:
self.update_information(game, igame, analysis, old_igame)
elif old_igame:
self.ui.title.setText(old_igame.title)
self.ui.remote_version.setText("...")
self.ui.local_version.setText("...")
self.ui.dl_size.setText("...")
self.ui.install_size.setText("...")
self.image.setPixmap(self.image_manager.get_pixmap(old_igame.app_name, color=True))
def update_information(self, game, igame, analysis, old_igame):
self.ui.title.setText(game.app_title)
self.ui.remote_version.setText(
elide_text(self.ui.remote_version, old_igame.version if old_igame else game.app_version(igame.platform))
)
self.ui.local_version.setText(elide_text(self.ui.local_version, igame.version))
self.ui.dl_size.setText(get_size(analysis.dl_size) if analysis else "")
self.ui.install_size.setText(get_size(analysis.install_size) if analysis else "")
self.image.setPixmap(self.image_manager.get_pixmap(game.app_name, color=True))
class UpdateWidget(QFrame):
enqueue = pyqtSignal(InstallOptionsModel)
def __init__(self, game: Game, igame: InstalledGame, parent=None):
super(UpdateWidget, self).__init__(parent=parent)
self.ui = Ui_DownloadWidget()
self.ui.setupUi(self)
# lk: setObjectName has to be after `setupUi` because it is also set in that function
self.setObjectName(widget_object_name(self, game.app_name))
self.game = game
self.igame = igame
self.ui.queue_buttons.setVisible(False)
self.ui.move_buttons.setVisible(False)
self.info_widget = InfoWidget(game, igame, parent=self)
self.ui.info_layout.addWidget(self.info_widget)
self.ui.update_button.clicked.connect(lambda: self.update_game(True))
self.ui.settings_button.clicked.connect(lambda: self.update_game(False))
def update_game(self, auto: bool):
self.ui.update_button.setDisabled(True)
self.ui.settings_button.setDisabled(True)
self.enqueue.emit(InstallOptionsModel(app_name=self.game.app_name, update=True, silent=auto)) # True if settings
def set_enabled(self, enabled: bool):
self.ui.update_button.setEnabled(enabled)
self.ui.settings_button.setEnabled(enabled)
def version(self) -> str:
return self.game.app_version(self.igame.platform)
class QueueWidget(QFrame):
# str: app_name
move_up = pyqtSignal(str)
# str: app_name
move_down = pyqtSignal(str)
# str: app_name
remove = pyqtSignal(str)
# InstallQueueItemModel
force = pyqtSignal(InstallQueueItemModel)
def __init__(self, item: InstallQueueItemModel, old_igame: InstalledGame, parent=None):
super(QueueWidget, self).__init__(parent=parent)
self.ui = Ui_DownloadWidget()
self.ui.setupUi(self)
# lk: setObjectName has to be after `setupUi` because it is also set in that function
self.setObjectName(widget_object_name(self, item.options.app_name))
self.threadpool = QThreadPool.globalInstance()
if not item:
self.ui.queue_buttons.setEnabled(False)
worker = InstallInfoWorker(RareCore.instance().core(), item.options)
worker.signals.result.connect(self.add_info_widget)
worker.signals.failed.connect(self.__on_info_worker_failed)
worker.signals.finished.connect(self.__on_info_worker_finished)
self.threadpool.start(worker)
self.info_widget = InfoWidget(None, None, None, old_igame, parent=self)
else:
self.info_widget = InfoWidget(
item.download.game, item.download.igame, item.download.analysis, old_igame, parent=self
)
self.ui.info_layout.addWidget(self.info_widget)
self.ui.update_buttons.setVisible(False)
self.old_igame = old_igame
self.item = item
self.ui.move_up_button.setIcon(icon("fa.arrow-up"))
self.ui.move_up_button.clicked.connect(
lambda: self.move_up.emit(self.item.options.app_name)
)
self.ui.move_down_button.setIcon(icon("fa.arrow-down"))
self.ui.move_down_button.clicked.connect(
lambda: self.move_down.emit(self.item.options.app_name)
)
self.ui.remove_button.clicked.connect(lambda: self.remove.emit(self.item.options.app_name))
self.ui.force_button.clicked.connect(lambda: self.force.emit(self.item))
@pyqtSlot(str)
def __on_info_worker_failed(self, message: str):
logger.error(f"Failed to requeue download for {self.item.options.app_name} with error: {message}")
self.remove.emit(self.item.options.app_name)
@pyqtSlot()
def __on_info_worker_finished(self):
logger.info(f"Download requeue worker finished for {self.item.options.app_name}")
@pyqtSlot(InstallDownloadModel)
def add_info_widget(self, download: InstallDownloadModel):
self.item.download = download
if self.item:
self.info_widget.update_information(download.game, download.igame, download.analysis, self.old_igame)
self.ui.queue_buttons.setEnabled(bool(self.item))
def toggle_arrows(self, index: int, length: int):
self.ui.move_up_button.setEnabled(bool(index))
self.ui.move_down_button.setEnabled(bool(length - (index + 1)))