diff --git a/rare/components/tabs/games/integrations/import_group.py b/rare/components/tabs/games/integrations/import_group.py index 442ef5ee..55ba9e81 100644 --- a/rare/components/tabs/games/integrations/import_group.py +++ b/rare/components/tabs/games/integrations/import_group.py @@ -4,10 +4,10 @@ from dataclasses import dataclass from enum import IntEnum from logging import getLogger from pathlib import Path -from typing import List, Tuple, Optional +from typing import List, Tuple, Optional, Set from PyQt5.QtCore import Qt, QModelIndex, pyqtSignal, QRunnable, QObject, QThreadPool, pyqtSlot -from PyQt5.QtGui import QStandardItemModel +from PyQt5.QtGui import QStandardItemModel, QShowEvent from PyQt5.QtWidgets import ( QFileDialog, QGroupBox, @@ -18,6 +18,7 @@ from PyQt5.QtWidgets import ( QStackedWidget, QProgressBar, QSizePolicy, + QFormLayout, ) from rare.lgndr.cli import LegendaryCLI @@ -138,7 +139,7 @@ class ImportWorker(QRunnable): class AppNameCompleter(QCompleter): activated = pyqtSignal(str) - def __init__(self, app_names: List, parent=None): + def __init__(self, app_names: Set[Tuple[str, str]], parent=None): super(AppNameCompleter, self).__init__(parent) # pylint: disable=E1136 super(AppNameCompleter, self).activated[QModelIndex].connect(self.__activated_idx) @@ -187,8 +188,8 @@ class ImportGroup(QGroupBox): self.worker: Optional[ImportWorker] = None self.threadpool = QThreadPool.globalInstance() - self.app_name_list = [rgame.app_name for rgame in self.rcore.games] - self.install_dir_list = [rgame.folder_name for rgame in self.rcore.games if not rgame.is_dlc] + self.__app_names: Set[str] = set() + self.__install_dirs: Set[str] = set() self.path_edit = PathEdit( self.core.get_default_install_dir(), @@ -197,23 +198,25 @@ class ImportGroup(QGroupBox): parent=self, ) self.path_edit.textChanged.connect(self.path_changed) - self.ui.path_edit_layout.addWidget(self.path_edit) + self.ui.import_layout.setWidget( + self.ui.import_layout.indexOf(self.ui.path_edit_label), QFormLayout.FieldRole, self.path_edit + ) self.app_name_edit = IndicatorLineEdit( placeholder=self.tr("Use in case the app name was not found automatically"), - completer=AppNameCompleter( - app_names=[(rgame.app_name, rgame.app_title) for rgame in self.rcore.games], - ), edit_func=self.app_name_edit_callback, parent=self, ) self.app_name_edit.textChanged.connect(self.app_name_changed) - self.ui.app_name_layout.addWidget(self.app_name_edit) + self.ui.import_layout.setWidget( + self.ui.import_layout.indexOf(self.ui.app_name_label), QFormLayout.FieldRole, self.app_name_edit + ) self.ui.import_folder_check.stateChanged.connect(self.import_folder_changed) self.ui.import_dlcs_check.setEnabled(False) self.ui.import_dlcs_check.stateChanged.connect(self.import_dlcs_changed) + self.ui.import_button_label.setText("") self.ui.import_button.setEnabled(False) self.ui.import_button.clicked.connect( lambda: self.__import(self.path_edit.text()) @@ -228,7 +231,17 @@ class ImportGroup(QGroupBox): self.info_progress = QProgressBar(self.button_info_stack) self.button_info_stack.addWidget(self.info_label) self.button_info_stack.addWidget(self.info_progress) - self.ui.button_info_layout.addWidget(self.button_info_stack) + self.ui.button_info_layout.insertWidget(0, self.button_info_stack) + + def showEvent(self, a0: QShowEvent) -> None: + if a0.spontaneous(): + return super().showEvent(a0) + self.__app_names = {rgame.app_name for rgame in self.rcore.games} + self.__install_dirs = {rgame.folder_name for rgame in self.rcore.games if not rgame.is_dlc} + self.app_name_edit.setCompleter( + AppNameCompleter(app_names={(rgame.app_name, rgame.app_title) for rgame in self.rcore.games}) + ) + super().showEvent(a0) def set_game(self, app_name: str): if app_name: @@ -240,7 +253,7 @@ class ImportGroup(QGroupBox): if os.path.exists(path): if os.path.exists(os.path.join(path, ".egstore")): return True, path, IndicatorReasonsCommon.VALID - elif os.path.basename(path) in self.install_dir_list: + elif os.path.basename(path) in self.__install_dirs: return True, path, IndicatorReasonsCommon.VALID else: return False, path, IndicatorReasonsCommon.DIR_NOT_EXISTS @@ -259,7 +272,7 @@ class ImportGroup(QGroupBox): def app_name_edit_callback(self, text) -> Tuple[bool, str, int]: if not text: return False, text, IndicatorReasonsCommon.UNDEFINED - if text in self.app_name_list: + if text in self.__app_names: return True, text, IndicatorReasonsCommon.VALID else: return False, text, IndicatorReasonsCommon.NOT_INSTALLED @@ -269,14 +282,12 @@ class ImportGroup(QGroupBox): self.info_label.setText("") self.ui.import_dlcs_check.setCheckState(Qt.Unchecked) self.ui.import_force_check.setCheckState(Qt.Unchecked) - if self.app_name_edit.is_valid: - self.ui.import_dlcs_check.setEnabled( - bool(self.core.get_dlc_for_game(app_name)) - ) - self.ui.import_button.setEnabled(not bool(self.worker) and self.path_edit.is_valid) - else: - self.ui.import_dlcs_check.setEnabled(False) - self.ui.import_button.setEnabled(False) + self.ui.import_dlcs_check.setEnabled( + self.app_name_edit.is_valid and bool(self.core.get_dlc_for_game(app_name)) + ) + self.ui.import_button.setEnabled( + not bool(self.worker) and (self.app_name_edit.is_valid and self.path_edit.is_valid) + ) @pyqtSlot(int) def import_folder_changed(self, state: Qt.CheckState): @@ -299,6 +310,11 @@ class ImportGroup(QGroupBox): @pyqtSlot(str) def __import(self, path: Optional[str] = None): + self.ui.import_button.setDisabled(True) + self.info_label.setText(self.tr("Status: Importing games")) + self.info_progress.setValue(0) + self.button_info_stack.setCurrentWidget(self.info_progress) + if not path: path = self.path_edit.text() self.worker = ImportWorker( @@ -309,12 +325,9 @@ class ImportGroup(QGroupBox): self.ui.import_dlcs_check.isChecked(), self.ui.import_force_check.isChecked() ) - self.worker.signals.result.connect(self.__on_import_result) self.worker.signals.progress.connect(self.__on_import_progress) + self.worker.signals.result.connect(self.__on_import_result) self.threadpool.start(self.worker) - self.button_info_stack.setCurrentWidget(self.info_progress) - self.info_label.setText(self.tr("Importing games")) - self.ui.import_button.setDisabled(True) @pyqtSlot(ImportedGame, int) def __on_import_progress(self, imported: ImportedGame, progress: int): @@ -345,7 +358,7 @@ class ImportGroup(QGroupBox): self.tr("Error: Could not find AppName for {}").format(res.path) ) else: - self.info_label.setText("") + self.info_label.setText(self.tr("Status: Finished importing games")) success = [r for r in result if r.result == ImportResult.SUCCESS] failure = [r for r in result if r.result == ImportResult.FAILED] errored = [r for r in result if r.result == ImportResult.ERROR] diff --git a/rare/ui/components/tabs/games/integrations/import_group.py b/rare/ui/components/tabs/games/integrations/import_group.py index 3f7796db..cc28fda1 100644 --- a/rare/ui/components/tabs/games/integrations/import_group.py +++ b/rare/ui/components/tabs/games/integrations/import_group.py @@ -2,7 +2,7 @@ # Form implementation generated from reading ui file 'rare/ui/components/tabs/games/integrations/import_group.ui' # -# Created by: PyQt5 UI code generator 5.15.9 +# Created by: PyQt5 UI code generator 5.15.10 # # 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. @@ -14,7 +14,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets class Ui_ImportGroup(object): def setupUi(self, ImportGroup): ImportGroup.setObjectName("ImportGroup") - ImportGroup.resize(501, 184) + ImportGroup.resize(506, 184) ImportGroup.setWindowTitle("ImportGroup") ImportGroup.setWindowFilePath("") self.import_layout = QtWidgets.QFormLayout(ImportGroup) @@ -23,15 +23,9 @@ class Ui_ImportGroup(object): self.path_edit_label = QtWidgets.QLabel(ImportGroup) self.path_edit_label.setObjectName("path_edit_label") self.import_layout.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.path_edit_label) - self.path_edit_layout = QtWidgets.QHBoxLayout() - self.path_edit_layout.setObjectName("path_edit_layout") - self.import_layout.setLayout(0, QtWidgets.QFormLayout.FieldRole, self.path_edit_layout) self.app_name_label = QtWidgets.QLabel(ImportGroup) self.app_name_label.setObjectName("app_name_label") self.import_layout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.app_name_label) - self.app_name_layout = QtWidgets.QHBoxLayout() - self.app_name_layout.setObjectName("app_name_layout") - self.import_layout.setLayout(1, QtWidgets.QFormLayout.FieldRole, self.app_name_layout) self.import_folder_label = QtWidgets.QLabel(ImportGroup) self.import_folder_label.setObjectName("import_folder_label") self.import_layout.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.import_folder_label) @@ -51,7 +45,7 @@ class Ui_ImportGroup(object): self.import_dlcs_check.setObjectName("import_dlcs_check") self.import_layout.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.import_dlcs_check) self.import_button_label = QtWidgets.QLabel(ImportGroup) - self.import_button_label.setText("") + self.import_button_label.setText("Error") self.import_button_label.setObjectName("import_button_label") self.import_layout.setWidget(5, QtWidgets.QFormLayout.LabelRole, self.import_button_label) self.button_info_layout = QtWidgets.QHBoxLayout() diff --git a/rare/ui/components/tabs/games/integrations/import_group.ui b/rare/ui/components/tabs/games/integrations/import_group.ui index c8499e03..43ed7e5e 100644 --- a/rare/ui/components/tabs/games/integrations/import_group.ui +++ b/rare/ui/components/tabs/games/integrations/import_group.ui @@ -6,7 +6,7 @@ 0 0 - 501 + 506 184 @@ -30,9 +30,6 @@ - - - @@ -40,9 +37,6 @@ - - - @@ -84,7 +78,7 @@ - + Error diff --git a/rare/widgets/indicator_edit.py b/rare/widgets/indicator_edit.py index e68414d1..1197407f 100644 --- a/rare/widgets/indicator_edit.py +++ b/rare/widgets/indicator_edit.py @@ -145,10 +145,7 @@ class IndicatorLineEdit(QWidget): self.line_edit.layout().setContentsMargins(0, 0, 10, 0) self.line_edit.layout().addWidget(self.hint_label) # Add completer - if completer is not None: - completer.popup().setItemDelegate(QStyledItemDelegate(self)) - completer.popup().setAlternatingRowColors(True) - self.line_edit.setCompleter(completer) + self.setCompleter(completer) layout.addWidget(self.line_edit) if edit_func is not None: self.indicator_label = QLabel() @@ -195,6 +192,16 @@ class IndicatorLineEdit(QWidget): self.hint_label.setFrameRect(self.line_edit.rect()) self.hint_label.setText(text) + def setCompleter(self, completer: Optional[QCompleter]): + if old := self.line_edit.completer(): + old.deleteLater() + if not completer: + self.line_edit.setCompleter(None) + return + completer.popup().setItemDelegate(QStyledItemDelegate(self)) + completer.popup().setAlternatingRowColors(True) + self.line_edit.setCompleter(completer) + def extend_reasons(self, reasons: Dict): self.__reasons.extend(reasons)