import os import platform from logging import getLogger from PyQt5.QtCore import Qt from PyQt5.QtWidgets import QHBoxLayout, QVBoxLayout, QLabel, QGroupBox, \ QCheckBox, QPushButton, QListWidgetItem, QDialog, QFileDialog import rare.shared as shared from rare.ui.components.tabs.games.import_sync.egl_sync_widget import Ui_EGLSyncGroup from rare.utils.extra_widgets import PathEdit logger = getLogger("EGLSync") class EGLSyncGroup(QGroupBox, Ui_EGLSyncGroup): importable_items = list() exportable_items = list() def __init__(self, parent=None): super(EGLSyncGroup, self).__init__(parent=parent) self.setupUi(self) self.egl_path_info.setText( self.tr("EGL path is at C:\\ProgramData\\Epic\\EpicGamesLauncher\\Data\\Manifests")) egl_path = os.path.expanduser("~/") if egl_path := shared.legendary_core.egl.programdata_path: pass elif egl_path := shared.legendary_core.lgd.config.get("default", "wine_prefix", fallback=""): egl_data_path = os.path.join(shared.legendary_core.lgd.config.get("default", "wine_prefix", fallback=""), 'drive_c/ProgramData/Epic/EpicGamesLauncher/Data') egl_path = os.path.join(egl_data_path, 'Manifests') else: possible_wine_prefixes = [os.path.expanduser("~/.wine"), os.path.expanduser("~/Games/epic-games-store")] for i in possible_wine_prefixes: if os.path.exists(p := os.path.join(i, "drive_c/ProgramData/Epic/EpicGamesLauncher/Data/Manifests")): egl_path = p self.egl_path_edit = PathEdit(egl_path, QFileDialog.DirectoryOnly, save_func=self.save_egl_path) self.egl_path_layout.addWidget(self.egl_path_edit) if platform.system() != "Windows": shared.legendary_core.lgd.config.set('Legendary', 'egl_programdata', egl_path) shared.legendary_core.egl.programdata_path = egl_path if shared.legendary_core.egl_sync_enabled: self.refresh_button.setText(self.tr("Disable sync")) else: self.refresh_button.setText(self.tr("Enable Sync")) self.refresh_button.clicked.connect(self.sync) # self.enable_sync_button.clicked.connect(self.enable_sync) # self.sync_once_button.clicked.connect(shared.lgd_core.egl_sync) self.export_list.itemDoubleClicked.connect( lambda item: item.setCheckState(Qt.Unchecked) if item.checkState() != Qt.Unchecked else item.setCheckState(Qt.Checked)) self.import_list.itemDoubleClicked.connect( lambda item: item.setCheckState(Qt.Unchecked) if item.checkState() != Qt.Unchecked else item.setCheckState(Qt.Checked)) self.export_select_all_button.clicked.connect( lambda: self.select_items(self.exportable_items, Qt.Checked)) self.export_select_none_button.clicked.connect( lambda: self.select_items(self.exportable_items, Qt.Unchecked)) self.import_select_all_button.clicked.connect( lambda: self.select_items(self.importable_items, Qt.Checked)) self.import_select_none_button.clicked.connect( lambda: self.select_items(self.importable_items, Qt.Unchecked)) self.export_button.clicked.connect(self.export_selected) self.import_button.clicked.connect(self.import_selected) def check_egl_path(self, path): pass def save_egl_path(self): shared.legendary_core.lgd.config.set("Legendary", "egl_programdata", self.egl_path_edit.text()) shared.legendary_core.egl.programdata_path = self.egl_path_edit.text() shared.legendary_core.lgd.save_config() self.update_lists() def update_export_list(self): self.export_button.setDisabled(not bool(shared.legendary_core.egl.programdata_path)) self.export_select_all_button.setDisabled(not bool(shared.legendary_core.egl.programdata_path)) self.export_select_none_button.setDisabled(not bool(shared.legendary_core.egl.programdata_path)) self.export_list.clear() self.exportable_items.clear() exportable_games = shared.legendary_core.egl_get_exportable() for igame in exportable_games: ew = EGLSyncItem(igame, True, self.export_list) self.exportable_items.append(ew) self.export_list.addItem(ew) self.export_group.setEnabled(bool(exportable_games)) self.export_button.setEnabled(bool(exportable_games)) self.export_label.setVisible(not bool(exportable_games)) def update_import_list(self): self.import_button.setDisabled(not bool(shared.legendary_core.egl.programdata_path)) self.import_select_all_button.setDisabled(not bool(shared.legendary_core.egl.programdata_path)) self.import_select_none_button.setDisabled(not bool(shared.legendary_core.egl.programdata_path)) self.import_list.clear() self.importable_items.clear() importable_games = shared.legendary_core.egl_get_importable() for game in importable_games: iw = EGLSyncItem(game, False, self.import_list) self.importable_items.append(iw) self.import_list.addItem(iw) self.import_group.setEnabled(bool(importable_games)) self.import_button.setEnabled(bool(importable_games)) self.import_label.setVisible(not bool(importable_games)) def update_lists(self): self.export_list.setVisible(bool(shared.legendary_core.egl.programdata_path)) self.import_list.setVisible(bool(shared.legendary_core.egl.programdata_path)) if not shared.legendary_core.egl.programdata_path: return self.update_export_list() self.update_import_list() def enable_sync(self): if not shared.legendary_core.egl.programdata_path: if os.path.exists(path := self.egl_path_edit.text()): shared.legendary_core.lgd.config.set("Legendary", "egl_programdata", path) shared.legendary_core.lgd.save_config() shared.legendary_core.egl.programdata_path = path shared.legendary_core.lgd.config.set('Legendary', 'egl_sync', "true") shared.legendary_core.egl_sync() shared.legendary_core.lgd.save_config() self.refresh_button.setText(self.tr("Disable Sync")) self.enable_sync_button.setDisabled(True) @staticmethod def select_items(item_list, state): for w in item_list: w.setCheckState(state) def export_selected(self): for ew in self.exportable_items: if ew.is_checked(): ew.export_game() self.export_list.takeItem(self.export_list.row(ew)) self.update_export_list() def import_selected(self): for iw in self.importable_items: if iw.is_checked: iw.import_game() self.import_list.takeItem(self.import_list.row(iw)) self.update_import_list() def sync(self): if shared.legendary_core.egl_sync_enabled: # disable sync info = DisableSyncDialog().get_information() if info[0] == 0: if info[1]: shared.legendary_core.lgd.config.remove_option('Legendary', 'egl_sync') else: shared.legendary_core.lgd.config.remove_option('Legendary', 'egl_programdata') shared.legendary_core.lgd.config.remove_option('Legendary', 'egl_sync') # remove EGL GUIDs from all games, DO NOT remove .egstore folders because that would fuck things up. for igame in shared.legendary_core.get_installed_list(): igame.egl_guid = '' shared.legendary_core.install_game(igame) shared.legendary_core.lgd.save_config() self.refresh_button.setText(self.tr("Enable Sync")) else: # enable sync # self.enable_sync_button.setDisabled(False) self.update_lists() class EGLSyncItem(QListWidgetItem): def __init__(self, game, export: bool, parent=None): super(EGLSyncItem, self).__init__(parent=parent) self.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsUserCheckable) self.setCheckState(Qt.Unchecked) self.game = game self.export = export if export: self.setText(game.title) else: self.setText(shared.legendary_core.get_game(game.app_name).app_title) def is_checked(self): return True if self.checkState() == Qt.Checked else False def export_game(self): shared.legendary_core.egl_export(self.game.app_name) def import_game(self): shared.legendary_core.egl_import(self.game.app_name) class DisableSyncDialog(QDialog): info = 1, False def __init__(self, parent=None): super(DisableSyncDialog, self).__init__(parent=parent) self.layout = QVBoxLayout() self.question = QLabel(self.tr("Do you really want to disable sync with Epic Games Store")) self.layout.addWidget(self.question) self.remove_metadata = QCheckBox(self.tr("Remove metadata from installed games")) self.layout.addWidget(self.remove_metadata) self.button_layout = QHBoxLayout() self.button_layout.addStretch(1) self.ok_button = QPushButton(self.tr("Ok")) self.cancel_button = QPushButton(self.tr("Cancel")) self.ok_button.clicked.connect(self.ok) self.cancel_button.clicked.connect(self.cancel) self.button_layout.addWidget(self.ok_button) self.button_layout.addWidget(self.cancel_button) self.layout.addStretch(1) self.layout.addLayout(self.button_layout) self.setLayout(self.layout) def ok(self): self.info = 0, self.remove_metadata.isChecked() self.close() def cancel(self): self.close() def get_information(self): self.exec_() return self.info class EGLSyncItemWidget(QGroupBox): def __init__(self, game, export: bool, parent=None): super(EGLSyncItemWidget, self).__init__(parent=parent) self.layout = QHBoxLayout() self.export = export self.game = game if export: self.app_title_label = QLabel(game.title) else: title = shared.legendary_core.get_game(game.app_name).app_title self.app_title_label = QLabel(title) self.layout.addWidget(self.app_title_label) self.button = QPushButton(self.tr("Export") if export else self.tr("Import")) if export: self.button.clicked.connect(self.export_game) else: self.button.clicked.connect(self.import_game) self.layout.addWidget(self.button) self.setLayout(self.layout) def export_game(self): shared.legendary_core.egl_export(self.game.app_name) # FIXME: on update_egl_widget this is going to crash because # FIXME: the item is not removed from the list in the python's side self.deleteLater() def import_game(self): shared.legendary_core.egl_import(self.game.app_name) # FIXME: on update_egl_widget this is going to crash because # FIXME: the item is not removed from the list in the python's side self.deleteLater()