diff --git a/rare/components/tabs/games/import_sync/import_group.py b/rare/components/tabs/games/import_sync/import_group.py index 9799ef8f..4100470f 100644 --- a/rare/components/tabs/games/import_sync/import_group.py +++ b/rare/components/tabs/games/import_sync/import_group.py @@ -3,7 +3,10 @@ import os from logging import getLogger from typing import Tuple -from PyQt5.QtWidgets import QFileDialog, QGroupBox +from PyQt5.QtCore import Qt, QModelIndex, pyqtSignal +from PyQt5.QtGui import QStandardItemModel +from PyQt5.QtWidgets import QFileDialog, QGroupBox, QCompleter, QListView +from legendary.core import LegendaryCore import rare.shared as shared from rare.ui.components.tabs.games.import_sync.import_group import Ui_ImportGroup @@ -13,12 +16,60 @@ from rare.utils.extra_widgets import IndicatorLineEdit, PathEdit logger = getLogger("Import") +class AppNameCompleter(QCompleter): + activated = pyqtSignal(str) + + def __init__(self, core: LegendaryCore, parent=None): + super(AppNameCompleter, self).__init__(parent) + super(AppNameCompleter, self).activated[QModelIndex].connect(self.__activated) + + app_names = [(i.app_name, i.app_title) for i in core.get_game_list()] + model = QStandardItemModel(len(app_names), 2) + for idx, game in enumerate(app_names): + app_name, app_title = game + model.setData(model.index(idx, 0), app_title) + model.setData(model.index(idx, 1), app_name) + self.setModel(model) + + # treeview = QTreeView() + # treeview.setRootIsDecorated(False) + # treeview.header().hide() + # treeview.header().setSectionResizeMode(0, QHeaderView.Stretch) + # treeview.header().setSectionResizeMode(1, QHeaderView.ResizeToContents) + # self.setPopup(treeview) + + listview = QListView() + # listview.setModelColumn(1) + self.setPopup(listview) + + self.setFilterMode(Qt.MatchContains) + self.setCaseSensitivity(Qt.CaseInsensitive) + # self.setCompletionMode(QCompleter.UnfilteredPopupCompletion) + + def __activated(self, idx_str): + # lk: don't even look at this in a funny way, it will die of shame + # lk: Note to self, the completer and popup models are different. + # lk: Getting the index from the popup and trying to use it in the completer will return invalid results + if isinstance(idx_str, QModelIndex): + self.activated.emit( + self.popup().model().data( + self.popup().model().index(idx_str.row(), 1) + ) + ) + # if isinstance(idx_str, str): + # # TODO: implement conversion from app_name to app_title (possible signal loop here?) + # self.activated.emit(idx_str) + + class ImportGroup(QGroupBox, Ui_ImportGroup): def __init__(self, parent=None): super(ImportGroup, self).__init__(parent=parent) self.setupUi(self) self.core = shared.core - self.game_list = [i.app_name for i in self.core.get_game_list()] + self.app_name_list = [game.app_name for game in self.core.get_game_list()] + self.install_dir_list = [ + game.metadata.get('customAttributes', {}).get('FolderName', {}).get('value', game.app_name) + for game in self.core.get_game_list(False) if not game.is_dlc] self.path_edit = PathEdit( self.core.get_default_install_dir(), @@ -31,6 +82,7 @@ class ImportGroup(QGroupBox, Ui_ImportGroup): self.app_name = IndicatorLineEdit( ph_text=self.tr("Use in case the app name was not found automatically"), + completer=AppNameCompleter(self.core), edit_func=self.app_name_edit_cb, parent=self ) @@ -44,9 +96,12 @@ class ImportGroup(QGroupBox, Ui_ImportGroup): if os.path.exists(path): if os.path.exists(os.path.join(path, ".egstore")): return True, path + elif os.path.basename(path) in self.install_dir_list: + return True, path return False, path def path_changed(self, path): + self.info_label.setText(str()) if self.path_edit.is_valid: self.app_name.setText(self.find_app_name(path)) else: @@ -55,12 +110,13 @@ class ImportGroup(QGroupBox, Ui_ImportGroup): def app_name_edit_cb(self, text) -> Tuple[bool, str]: if not text: return False, text - if text in self.game_list: + if text in self.app_name_list: return True, text else: return False, text def app_name_changed(self, text): + self.info_label.setText(str()) if self.app_name.is_valid: self.import_button.setEnabled(True) else: @@ -93,10 +149,10 @@ class ImportGroup(QGroupBox, Ui_ImportGroup): if legendary_utils.import_game(self.core, app_name=app_name, path=path): self.info_label.setText(self.tr("Successfully imported {}. Reload library").format( self.core.get_installed_game(app_name).title)) - self.app_name.setText("") + self.app_name.setText(str()) - shared.signals.update_gamelist.emit(app_name) + shared.signals.update_gamelist.emit([app_name]) else: - logger.warning("Failed to import" + app_name) + logger.warning(f'Failed to import "{app_name}"') self.info_label.setText(self.tr("Failed to import {}").format(app_name)) return diff --git a/rare/resources/stylesheets/RareStyle/stylesheet.qss b/rare/resources/stylesheets/RareStyle/stylesheet.qss index bd9adf83..6c3ba91d 100644 --- a/rare/resources/stylesheets/RareStyle/stylesheet.qss +++ b/rare/resources/stylesheets/RareStyle/stylesheet.qss @@ -214,6 +214,8 @@ QTableView { background-color: #202225; alternate-background-color: #282a2e; } + +QListView::item, QTreeView::item { margin-right: 1px; } diff --git a/rare/utils/extra_widgets.py b/rare/utils/extra_widgets.py index 321248df..f73d3335 100644 --- a/rare/utils/extra_widgets.py +++ b/rare/utils/extra_widgets.py @@ -147,6 +147,7 @@ class IndicatorLineEdit(QWidget): self.line_edit.setSizePolicy(horiz_policy, QSizePolicy.Fixed) if completer is not None: completer.popup().setItemDelegate(QStyledItemDelegate(self)) + completer.popup().setAlternatingRowColors(True) self.line_edit.setCompleter(completer) self.layout.addWidget(self.line_edit) if edit_func is not None: @@ -234,7 +235,7 @@ class PathEditIconProvider(QFileIconProvider): class PathEdit(IndicatorLineEdit): - compl = QCompleter() + completer = QCompleter() compl_model = QFileSystemModel() def __init__(self, @@ -252,8 +253,8 @@ class PathEdit(IndicatorLineEdit): QFileSystemModel.DontUseCustomDirectoryIcons) self.compl_model.setIconProvider(PathEditIconProvider()) self.compl_model.setRootPath(path) - self.compl.setModel(self.compl_model) - super(PathEdit, self).__init__(text=path, ph_text=ph_text, completer=self.compl, + self.completer.setModel(self.compl_model) + super(PathEdit, self).__init__(text=path, ph_text=ph_text, completer=self.completer, edit_func=edit_func, save_func=save_func, horiz_policy=horiz_policy, parent=parent) self.setObjectName("PathEdit")