From a246f4ee1650906f29f9fb7540e7afed30ddb09a Mon Sep 17 00:00:00 2001
From: loathingKernel <142770+loathingKernel@users.noreply.github.com>
Date: Fri, 8 Sep 2023 19:38:39 +0300
Subject: [PATCH] EosGroup: Remake the UI and integrate with Rare's facilities
* Uninstalling the Overlay now goes through the same procedure as
uninstalling any other game.
* The available prefixes are now listed instead of hiding them inside
a combo box.
* Each listing works indepedently to enable/disable the Overlay for the prefix
---
rare/components/dialogs/uninstall_dialog.py | 10 +-
rare/components/tabs/downloads/__init__.py | 5 +-
.../tabs/games/integrations/__init__.py | 4 +-
.../tabs/games/integrations/eos_group.py | 296 +++++++++---------
rare/models/install.py | 9 +-
rare/models/signals.py | 6 +-
rare/shared/rare_core.py | 10 +-
rare/shared/workers/uninstall.py | 43 ++-
.../tabs/games/integrations/eos_widget.py | 160 ++++------
.../tabs/games/integrations/eos_widget.ui | 287 +++++++----------
10 files changed, 375 insertions(+), 455 deletions(-)
diff --git a/rare/components/dialogs/uninstall_dialog.py b/rare/components/dialogs/uninstall_dialog.py
index c6f24cae..dd6be379 100644
--- a/rare/components/dialogs/uninstall_dialog.py
+++ b/rare/components/dialogs/uninstall_dialog.py
@@ -23,14 +23,21 @@ class UninstallDialog(ButtonDialog):
self.keep_files = QCheckBox(self.tr("Keep files"))
self.keep_files.setChecked(bool(options.keep_files))
+ self.keep_files.setEnabled(not rgame.is_overlay)
self.keep_config = QCheckBox(self.tr("Keep configuation"))
self.keep_config.setChecked(bool(options.keep_config))
+ self.keep_config.setEnabled(not rgame.is_overlay)
+
+ self.keep_overlay_keys = QCheckBox(self.tr("Keep EOS Overlay registry keys"))
+ self.keep_overlay_keys.setChecked(bool(options.keep_overlay_keys))
+ self.keep_overlay_keys.setEnabled(rgame.is_overlay)
layout = QVBoxLayout()
layout.addWidget(title_label)
layout.addWidget(self.keep_files)
layout.addWidget(self.keep_config)
+ layout.addWidget(self.keep_overlay_keys)
self.setCentralLayout(layout)
@@ -51,7 +58,8 @@ class UninstallDialog(ButtonDialog):
True,
self.keep_files.isChecked(),
self.keep_config.isChecked(),
+ self.keep_overlay_keys.isChecked(),
)
def reject_handler(self):
- self.options.values = (None, None, None)
+ self.options.values = (None, None, None, None)
diff --git a/rare/components/tabs/downloads/__init__.py b/rare/components/tabs/downloads/__init__.py
index 9166f724..85df8598 100644
--- a/rare/components/tabs/downloads/__init__.py
+++ b/rare/components/tabs/downloads/__init__.py
@@ -238,10 +238,7 @@ class DownloadsTab(QWidget):
else:
logger.info(f"Created desktop link {result.shortcut_name} for {result.options.app_name}")
- if result.options.overlay:
- self.signals.application.overlay_installed.emit()
- else:
- self.signals.application.notify.emit(result.options.app_name)
+ self.signals.application.notify.emit(result.options.app_name)
if self.updates_group.contains(result.options.app_name):
self.updates_group.set_widget_enabled(result.options.app_name, True)
diff --git a/rare/components/tabs/games/integrations/__init__.py b/rare/components/tabs/games/integrations/__init__.py
index 0a3bf0fb..0ecbc088 100644
--- a/rare/components/tabs/games/integrations/__init__.py
+++ b/rare/components/tabs/games/integrations/__init__.py
@@ -5,7 +5,7 @@ from PyQt5.QtWidgets import QVBoxLayout, QWidget, QLabel, QSpacerItem, QSizePoli
from rare.widgets.side_tab import SideTabWidget
from .egl_sync_group import EGLSyncGroup
-from .eos_group import EOSGroup
+from .eos_group import EosGroup
from .import_group import ImportGroup
from .ubisoft_group import UbisoftGroup
@@ -35,7 +35,7 @@ class IntegrationsTabs(SideTabWidget):
self,
)
self.ubisoft_group = UbisoftGroup(self.eos_ubisoft)
- self.eos_group = EOSGroup(self.eos_ubisoft)
+ self.eos_group = EosGroup(self.eos_ubisoft)
self.eos_ubisoft.addWidget(self.eos_group)
self.eos_ubisoft.addWidget(self.ubisoft_group)
self.eos_ubisoft_index = self.addTab(self.eos_ubisoft, self.tr("Epic Overlay and Ubisoft"))
diff --git a/rare/components/tabs/games/integrations/eos_group.py b/rare/components/tabs/games/integrations/eos_group.py
index 9e541d25..154c820f 100644
--- a/rare/components/tabs/games/integrations/eos_group.py
+++ b/rare/components/tabs/games/integrations/eos_group.py
@@ -1,161 +1,189 @@
import os
import platform
from logging import getLogger
-from typing import List
+from typing import Optional
-from PyQt5.QtCore import QRunnable, QObject, pyqtSignal, QThreadPool
-from PyQt5.QtWidgets import QGroupBox, QMessageBox
+from PyQt5.QtCore import QRunnable, QObject, pyqtSignal, QThreadPool, Qt, pyqtSlot, QSize
+from PyQt5.QtWidgets import QGroupBox, QMessageBox, QFrame, QHBoxLayout, QSizePolicy, QLabel, QPushButton, QFormLayout
from legendary.lfs import eos
-from rare.models.install import InstallOptionsModel
-from rare.shared import LegendaryCoreSingleton, GlobalSignalsSingleton
+from rare.lgndr.core import LegendaryCore
+from rare.models.game import RareEosOverlay
+from rare.shared import RareCore
from rare.ui.components.tabs.games.integrations.eos_widget import Ui_EosWidget
+from rare.utils import config_helper
from rare.utils.misc import icon
+from rare.widgets.elide_label import ElideLabel
logger = getLogger("EpicOverlay")
-def get_wine_prefixes() -> List[str]:
- prefixes = list()
- if os.path.exists(p := os.path.expanduser("~/.wine")):
- prefixes.append(p)
-
- for name, section in LegendaryCoreSingleton().lgd.config.items():
- pfx = section.get("WINEPREFIX") or section.get("wine_prefix")
- if pfx and pfx not in prefixes:
- prefixes.append(pfx)
-
- return prefixes
-
-
class CheckForUpdateWorker(QRunnable):
class CheckForUpdateSignals(QObject):
update_available = pyqtSignal(bool)
- def __init__(self):
+ def __init__(self, core: LegendaryCore):
super(CheckForUpdateWorker, self).__init__()
self.signals = self.CheckForUpdateSignals()
self.setAutoDelete(True)
- self.core = LegendaryCoreSingleton()
+ self.core = core
def run(self) -> None:
self.core.check_for_overlay_updates()
self.signals.update_available.emit(self.core.overlay_update_available)
-class EOSGroup(QGroupBox):
+class EosPrefixWidget(QFrame):
+ def __init__(self, overlay: RareEosOverlay, prefix: Optional[str], parent=None):
+ super(EosPrefixWidget, self).__init__(parent=parent)
+ self.setFrameShape(QFrame.StyledPanel)
+ self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
+
+ self.indicator = QLabel(parent=self)
+ self.indicator.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Preferred)
+
+ self.label = ElideLabel(
+ prefix if prefix is not None else "Epic Online Services Overlay",
+ parent=self
+ )
+
+ self.button = QPushButton(parent=self)
+ self.button.setMinimumWidth(150)
+ self.button.clicked.connect(self.action)
+
+ layout = QHBoxLayout(self)
+ layout.setContentsMargins(-1, 0, 0, 0)
+ layout.addWidget(self.indicator)
+ layout.addWidget(self.label, stretch=1)
+ layout.addWidget(self.button)
+
+ self.overlay = overlay
+ self.prefix = prefix
+
+ self.overlay.signals.game.installed.connect(self.update_state)
+ self.overlay.signals.game.uninstalled.connect(self.update_state)
+
+ self.update_state()
+
+ @pyqtSlot()
+ def update_state(self):
+ if not self.overlay.is_installed:
+ self.setDisabled(True)
+ self.button.setText(self.tr("Unavailable"))
+ self.indicator.setPixmap(icon("fa.circle-o", color="grey").pixmap(20, 20))
+ return
+
+ self.setDisabled(False)
+ if self.overlay.is_enabled(self.prefix):
+ self.button.setText(self.tr("Disable overlay"))
+ self.indicator.setPixmap(
+ icon("fa.check-circle-o", color="green").pixmap(QSize(20, 20))
+ )
+ else:
+ self.button.setText(self.tr("Enable overlay"))
+ self.indicator.setPixmap(
+ icon("fa.times-circle-o", color="red").pixmap(QSize(20, 20))
+ )
+
+ @pyqtSlot()
+ def action(self):
+ if self.overlay.is_enabled(self.prefix):
+ self.overlay.disable(prefix=self.prefix)
+ else:
+ self.overlay.enable(prefix=self.prefix)
+ self.update_state()
+
+
+class EosGroup(QGroupBox):
def __init__(self, parent=None):
- super(EOSGroup, self).__init__(parent=parent)
+ super(EosGroup, self).__init__(parent=parent)
self.ui = Ui_EosWidget()
self.ui.setupUi(self)
# lk: set object names for CSS properties
self.ui.install_button.setObjectName("InstallButton")
- self.ui.install_button.setIcon(icon("ri.install-line"))
self.ui.uninstall_button.setObjectName("UninstallButton")
+
+ self.ui.install_page_layout.setAlignment(Qt.AlignTop)
+ self.ui.info_page_layout.setAlignment(Qt.AlignTop)
+
+ self.ui.install_button.setIcon(icon("ri.install-line"))
self.ui.uninstall_button.setIcon(icon("ri.uninstall-line"))
- self.core = LegendaryCoreSingleton()
- self.signals = GlobalSignalsSingleton()
+ self.installed_path_label = ElideLabel(parent=self)
+ self.installed_version_label = ElideLabel(parent=self)
- self.prefix_enabled = False
+ self.ui.info_label_layout.setWidget(0, QFormLayout.FieldRole, self.installed_version_label)
+ self.ui.info_label_layout.setWidget(1, QFormLayout.FieldRole, self.installed_path_label)
- self.ui.enabled_cb.stateChanged.connect(self.change_enable)
+ self.rcore = RareCore.instance()
+ self.core = self.rcore.core()
+ self.signals = self.rcore.signals()
+ self.overlay = self.rcore.get_overlay()
+
+ self.overlay.signals.game.installed.connect(self.install_finished)
+ self.overlay.signals.game.uninstalled.connect(self.uninstall_finished)
+
+ self.ui.install_button.clicked.connect(self.install_overlay)
+ self.ui.update_button.clicked.connect(self.install_overlay)
self.ui.uninstall_button.clicked.connect(self.uninstall_overlay)
- self.ui.update_button.setVisible(False)
- self.overlay = self.core.lgd.get_overlay_install_info()
-
- self.signals.application.overlay_installed.connect(self.overlay_installation_finished)
- self.signals.application.prefix_updated.connect(self.update_prefixes)
-
- self.ui.update_check_button.clicked.connect(self.check_for_update)
- self.ui.install_button.clicked.connect(self.install_overlay)
- self.ui.update_button.clicked.connect(lambda: self.install_overlay(True))
-
- if self.overlay: # installed
- self.ui.installed_version_lbl.setText(f"{self.overlay.version}")
- self.ui.installed_path_lbl.setText(f"{self.overlay.install_path}")
- self.ui.overlay_stack.setCurrentIndex(0)
+ if self.overlay.is_installed: # installed
+ self.installed_version_label.setText(f"{self.overlay.version}")
+ self.installed_path_label.setText(self.overlay.install_path)
+ self.ui.overlay_stack.setCurrentWidget(self.ui.info_page)
else:
- self.ui.overlay_stack.setCurrentIndex(1)
- self.ui.enable_frame.setDisabled(True)
-
- if platform.system() == "Windows":
- self.current_prefix = None
- self.ui.select_pfx_combo.setVisible(False)
- else:
- self.current_prefix = os.path.expanduser("~/.wine") \
- if os.path.exists(os.path.expanduser("~/.wine")) \
- else None
- pfxs = get_wine_prefixes()
- for pfx in pfxs:
- self.ui.select_pfx_combo.addItem(pfx.replace(os.path.expanduser("~/"), "~/"))
- if not pfxs:
- self.ui.enable_frame.setDisabled(True)
- else:
- self.ui.select_pfx_combo.setCurrentIndex(0)
-
- self.ui.select_pfx_combo.currentIndexChanged.connect(self.update_select_combo)
- if pfxs:
- self.update_select_combo(None)
-
- self.ui.enabled_info_label.setText("")
+ self.ui.overlay_stack.setCurrentWidget(self.ui.install_page)
+ self.ui.update_button.setEnabled(False)
self.threadpool = QThreadPool.globalInstance()
+ def showEvent(self, a0) -> None:
+ self.check_for_update()
+ self.update_prefixes()
+ super().showEvent(a0)
+
def update_prefixes(self):
- logger.debug("Updated prefixes")
- pfxs = get_wine_prefixes() # returns /home/whatever
- self.ui.select_pfx_combo.clear()
+ for widget in self.findChildren(EosPrefixWidget, options=Qt.FindDirectChildrenOnly):
+ widget.deleteLater()
- for pfx in pfxs:
- self.ui.select_pfx_combo.addItem(pfx.replace(os.path.expanduser("~/"), "~/"))
-
- if self.current_prefix in pfxs:
- self.ui.select_pfx_combo.setCurrentIndex(
- self.ui.select_pfx_combo.findText(self.current_prefix.replace(os.path.expanduser("~/"), "~/")))
+ if platform.system() != "Windows":
+ prefixes = config_helper.get_wine_prefixes()
+ if platform.system() == "Darwin":
+ # TODO: add crossover support
+ pass
+ for prefix in prefixes:
+ widget = EosPrefixWidget(self.overlay, prefix)
+ self.ui.eos_layout.addWidget(widget)
+ logger.debug("Updated prefixes")
+ else:
+ widget = EosPrefixWidget(self.overlay, None)
+ self.ui.eos_layout.addWidget(widget)
def check_for_update(self):
- def worker_finished(update_available):
- self.ui.update_button.setVisible(update_available)
- self.ui.update_check_button.setDisabled(False)
- if not update_available:
- self.ui.update_check_button.setText(self.tr("No update available"))
+ if not self.overlay.is_installed:
+ return
- self.ui.update_check_button.setDisabled(True)
- worker = CheckForUpdateWorker()
+ def worker_finished(update_available):
+ self.ui.update_button.setEnabled(update_available)
+
+ worker = CheckForUpdateWorker(self.core)
worker.signals.update_available.connect(worker_finished)
QThreadPool.globalInstance().start(worker)
- def overlay_installation_finished(self):
- self.overlay = self.core.lgd.get_overlay_install_info()
-
- if not self.overlay:
- logger.error("Something went wrong, when installing overlay")
- QMessageBox.warning(self, "Error", self.tr("Something went wrong, when installing overlay"))
+ @pyqtSlot()
+ def install_finished(self):
+ if not self.overlay.is_installed:
+ logger.error("Something went wrong while installing overlay")
+ QMessageBox.warning(self, "Error", self.tr("Something went wrong while installing Overlay"))
return
+ self.ui.overlay_stack.setCurrentWidget(self.ui.info_page)
+ self.installed_version_label.setText(f"{self.overlay.version}")
+ self.installed_path_label.setText(self.overlay.install_path)
+ self.ui.update_button.setEnabled(False)
- self.ui.overlay_stack.setCurrentIndex(0)
- self.ui.installed_version_lbl.setText(f"{self.overlay.version}")
- self.ui.installed_path_lbl.setText(f"{self.overlay.install_path}")
-
- self.ui.update_button.setVisible(False)
-
- self.ui.enable_frame.setEnabled(True)
-
- def update_select_combo(self, i: None):
- if i is None:
- i = self.ui.select_pfx_combo.currentIndex()
- prefix = os.path.expanduser(self.ui.select_pfx_combo.itemText(i))
- if platform.system() != "Windows" and not os.path.isfile(os.path.join(prefix, "user.reg")):
- return
- self.current_prefix = prefix
- reg_paths = eos.query_registry_entries(self.current_prefix)
-
- overlay_enabled = False
- if reg_paths['overlay_path'] and self.core.is_overlay_install(reg_paths['overlay_path']):
- overlay_enabled = True
- self.ui.enabled_cb.setChecked(overlay_enabled)
+ @pyqtSlot()
+ def uninstall_finished(self):
+ self.ui.overlay_stack.setCurrentWidget(self.ui.install_page)
def change_enable(self):
enabled = self.ui.enabled_cb.isChecked()
@@ -170,7 +198,7 @@ class EOSGroup(QGroupBox):
logger.info("Disabled Epic Overlay")
self.ui.enabled_info_label.setText(self.tr("Disabled"))
else:
- if not self.overlay:
+ if not self.overlay.is_installed:
available_installs = self.core.search_overlay_installs(self.current_prefix)
if not available_installs:
logger.error('No EOS overlay installs found!')
@@ -209,51 +237,13 @@ class EOSGroup(QGroupBox):
self.ui.enabled_info_label.setText(self.tr("Enabled"))
logger.info(f'Enabled overlay at: {path}')
- def update_checkbox(self):
- reg_paths = eos.query_registry_entries(self.current_prefix)
- enabled = False
- if reg_paths['overlay_path'] and self.core.is_overlay_install(reg_paths['overlay_path']):
- enabled = True
- self.ui.enabled_cb.setChecked(enabled)
-
- def install_overlay(self, update=False):
- base_path = os.path.join(self.core.get_default_install_dir(), ".overlay")
- if update:
- if not self.overlay:
- self.ui.overlay_stack.setCurrentIndex(1)
- self.ui.enable_frame.setDisabled(True)
- QMessageBox.warning(self, "Warning", self.tr("Overlay is not installed. Could not update"))
- return
- base_path = self.overlay.install_path
-
- options = InstallOptionsModel(
- app_name=eos.EOSOverlayApp.app_name, base_path=base_path, platform="Windows", overlay=True
- )
-
- self.signals.game.install.emit(options)
+ @pyqtSlot()
+ def install_overlay(self):
+ self.overlay.install()
def uninstall_overlay(self):
- if not self.core.is_overlay_installed():
- logger.error('No legendary-managed overlay installation found.')
- self.ui.overlay_stack.setCurrentIndex(1)
+ if not self.overlay.is_installed:
+ logger.error('No Rare-managed overlay installation found.')
+ self.ui.overlay_stack.setCurrentWidget(self.ui.install_page)
return
-
- if QMessageBox.No == QMessageBox.question(
- self, "Uninstall Overlay", self.tr("Do you want to uninstall overlay?"),
- QMessageBox.Yes | QMessageBox.No, QMessageBox.No
- ):
- return
- if platform.system() == "Windows":
- eos.remove_registry_entries(None)
- else:
- for prefix in [self.ui.select_pfx_combo.itemText(i) for i in range(self.ui.select_pfx_combo.count())]:
- logger.info(f"Removing registry entries from {prefix}")
- try:
- eos.remove_registry_entries(os.path.expanduser(prefix))
- except Exception as e:
- logger.warning(f"{prefix}: {e}")
-
- self.core.remove_overlay_install()
- self.ui.overlay_stack.setCurrentIndex(1)
-
- self.ui.enable_frame.setDisabled(True)
+ self.overlay.uninstall()
diff --git a/rare/models/install.py b/rare/models/install.py
index 69123d0b..0a4965d6 100644
--- a/rare/models/install.py
+++ b/rare/models/install.py
@@ -86,6 +86,7 @@ class UninstallOptionsModel:
accepted: bool = None
keep_files: bool = None
keep_config: bool = None
+ keep_overlay_keys: bool = None
def __bool__(self):
return (
@@ -93,20 +94,21 @@ class UninstallOptionsModel:
and (self.accepted is not None)
and (self.keep_files is not None)
and (self.keep_config is not None)
+ and (self.keep_overlay_keys is not None)
)
@property
- def values(self) -> Tuple[bool, bool, bool]:
+ def values(self) -> Tuple[bool, bool, bool, bool]:
"""
This model's options
:return:
Tuple of `accepted` `keep_files` `keep_config` `keep_overlay_keys`
"""
- return self.accepted, self.keep_config, self.keep_files
+ return self.accepted, self.keep_config, self.keep_files, self.keep_overlay_keys
@values.setter
- def values(self, values: Tuple[bool, bool, bool]):
+ def values(self, values: Tuple[bool, bool, bool, bool]):
"""
Set this model's options
@@ -117,6 +119,7 @@ class UninstallOptionsModel:
self.accepted = values[0]
self.keep_files = values[1]
self.keep_config = values[2]
+ self.keep_overlay_keys = values[3]
@dataclass
diff --git a/rare/models/signals.py b/rare/models/signals.py
index 8377e2d3..3c614237 100644
--- a/rare/models/signals.py
+++ b/rare/models/signals.py
@@ -10,14 +10,12 @@ class GlobalSignals:
class ApplicationSignals(QObject):
# int: exit code
- quit = pyqtSignal(int)
+ quit = pyqtSignal(int)
# str: app_title
notify = pyqtSignal(str)
# none
prefix_updated = pyqtSignal()
# none
- overlay_installed = pyqtSignal()
- # none
update_tray = pyqtSignal()
# none
update_statusbar = pyqtSignal()
@@ -58,4 +56,4 @@ class GlobalSignals:
self.download.deleteLater()
del self.download
self.discord_rpc.deleteLater()
- del self.discord_rpc
\ No newline at end of file
+ del self.discord_rpc
diff --git a/rare/shared/rare_core.py b/rare/shared/rare_core.py
index 6000a3b9..31a80f06 100644
--- a/rare/shared/rare_core.py
+++ b/rare/shared/rare_core.py
@@ -66,6 +66,8 @@ class RareCore(QObject):
self.__library: Dict[str, RareGame] = {}
self.__eos_overlay = RareEosOverlay(self.__core, EOSOverlayApp)
+ self.__eos_overlay.signals.game.install.connect(self.__signals.game.install)
+ self.__eos_overlay.signals.game.uninstall.connect(self.__signals.game.uninstall)
RareCore.__instance = self
@@ -224,12 +226,12 @@ class RareCore(QObject):
for dlc in rgame.owned_dlcs:
if dlc.is_installed:
logger.info(f'Uninstalling DLC "{dlc.app_name}" ({dlc.app_title})...')
- uninstall_game(self.__core, dlc.app_name, keep_files=True, keep_config=True)
+ uninstall_game(self.__core, dlc, keep_files=True, keep_config=True)
dlc.igame = None
logger.info(
f'Removing "{rgame.app_title}" because "{rgame.igame.install_path}" does not exist...'
)
- uninstall_game(self.__core, rgame.app_name, keep_files=True, keep_config=True)
+ uninstall_game(self.__core, rgame, keep_files=True, keep_config=True)
logger.info(f"Uninstalled {rgame.app_title}, because no game files exist")
rgame.igame = None
return
@@ -254,6 +256,9 @@ class RareCore(QObject):
return self.__eos_overlay
return self.__library[app_name]
+ def get_overlay(self):
+ return self.get_game(EOSOverlayApp.app_name)
+
def __add_game(self, rgame: RareGame) -> None:
rgame.signals.download.enqueue.connect(self.__signals.download.enqueue)
rgame.signals.download.dequeue.connect(self.__signals.download.dequeue)
@@ -345,7 +350,6 @@ class RareCore(QObject):
start_time = time.time()
try:
entitlements = self.__core.egs.get_user_entitlements()
- self.__core.lgd.entitlements = entitlements
for game in self.__library.values():
game.grant_date()
except (HTTPError, ConnectionError) as e:
diff --git a/rare/shared/workers/uninstall.py b/rare/shared/workers/uninstall.py
index 76207fe7..9b154ce8 100644
--- a/rare/shared/workers/uninstall.py
+++ b/rare/shared/workers/uninstall.py
@@ -1,7 +1,10 @@
+import platform
from logging import getLogger
+from typing import Tuple
from PyQt5.QtCore import QObject, pyqtSignal
from legendary.core import LegendaryCore
+from legendary.lfs.eos import remove_registry_entries
from rare.lgndr.cli import LegendaryCLI
from rare.lgndr.glue.arguments import LgndrUninstallGameArgs
@@ -16,14 +19,36 @@ logger = getLogger("UninstallWorker")
# TODO: You can use RareGame directly here once this is called inside RareCore and skip metadata fetch
-def uninstall_game(core: LegendaryCore, app_name: str, keep_files=False, keep_config=False):
- game = core.get_game(app_name)
+def uninstall_game(
+ core: LegendaryCore, rgame: RareGame, keep_files=False, keep_config=False, keep_overlay_keys=False
+) -> Tuple[bool, str]:
+ if rgame.is_overlay:
+ logger.info('Deleting overlay installation...')
+ core.remove_overlay_install()
+
+ if keep_overlay_keys:
+ return True, ""
+
+ logger.info('Removing registry entries...')
+ if platform.system() != "Window":
+ prefixes = config_helper.get_wine_prefixes()
+ if platform.system() == "Darwin":
+ # TODO: add crossover support
+ pass
+ if prefixes is not None:
+ for prefix in prefixes:
+ remove_registry_entries(prefix)
+ logger.debug("Removed registry entries for prefix %s", prefix)
+ else:
+ remove_registry_entries(None)
+
+ return True, ""
# remove shortcuts link
if desktop_links_supported():
for link_type in desktop_link_types():
link_path = desktop_link_path(
- game.metadata.get("customAttributes", {}).get("FolderName", {}).get("value"), link_type
+ rgame.game.metadata.get("customAttributes", {}).get("FolderName", {}).get("value"), link_type
)
if link_path.exists():
link_path.unlink(missing_ok=True)
@@ -31,7 +56,7 @@ def uninstall_game(core: LegendaryCore, app_name: str, keep_files=False, keep_co
status = LgndrIndirectStatus()
LegendaryCLI(core).uninstall_game(
LgndrUninstallGameArgs(
- app_name=app_name,
+ app_name=rgame.app_name,
keep_files=keep_files,
skip_uninstaller=False,
yes=True,
@@ -40,8 +65,8 @@ def uninstall_game(core: LegendaryCore, app_name: str, keep_files=False, keep_co
)
if not keep_config:
logger.info("Removing sections in config file")
- config_helper.remove_section(app_name)
- config_helper.remove_section(f"{app_name}.env")
+ config_helper.remove_section(rgame.app_name)
+ config_helper.remove_section(f"{rgame.app_name}.env")
config_helper.save_config()
@@ -62,7 +87,11 @@ class UninstallWorker(Worker):
def run_real(self) -> None:
self.rgame.state = RareGame.State.UNINSTALLING
success, message = uninstall_game(
- self.core, self.rgame.app_name, self.options.keep_files, self.options.keep_config
+ self.core,
+ self.rgame,
+ self.options.keep_files,
+ self.options.keep_config,
+ self.options.keep_overlay_keys,
)
self.rgame.state = RareGame.State.IDLE
self.signals.result.emit(self.rgame, success, message)
diff --git a/rare/ui/components/tabs/games/integrations/eos_widget.py b/rare/ui/components/tabs/games/integrations/eos_widget.py
index 8b856256..3efcf3f9 100644
--- a/rare/ui/components/tabs/games/integrations/eos_widget.py
+++ b/rare/ui/components/tabs/games/integrations/eos_widget.py
@@ -14,102 +14,71 @@ from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_EosWidget(object):
def setupUi(self, EosWidget):
EosWidget.setObjectName("EosWidget")
- EosWidget.resize(586, 146)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Maximum)
- sizePolicy.setHorizontalStretch(0)
- sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(EosWidget.sizePolicy().hasHeightForWidth())
- EosWidget.setSizePolicy(sizePolicy)
+ EosWidget.resize(464, 98)
EosWidget.setWindowTitle("GroupBox")
- self.eos_layout = QtWidgets.QHBoxLayout(EosWidget)
+ self.eos_layout = QtWidgets.QVBoxLayout(EosWidget)
self.eos_layout.setSizeConstraint(QtWidgets.QLayout.SetDefaultConstraint)
self.eos_layout.setObjectName("eos_layout")
self.overlay_stack = QtWidgets.QStackedWidget(EosWidget)
- self.overlay_stack.setFrameShape(QtWidgets.QFrame.StyledPanel)
- self.overlay_stack.setFrameShadow(QtWidgets.QFrame.Raised)
self.overlay_stack.setObjectName("overlay_stack")
- self.overlay_info_page = QtWidgets.QWidget()
- self.overlay_info_page.setObjectName("overlay_info_page")
- self.overlay_info_layout = QtWidgets.QFormLayout(self.overlay_info_page)
- self.overlay_info_layout.setLabelAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
- self.overlay_info_layout.setFormAlignment(QtCore.Qt.AlignBottom|QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft)
- self.overlay_info_layout.setObjectName("overlay_info_layout")
- self.installed_version_info_lbl = QtWidgets.QLabel(self.overlay_info_page)
- self.installed_version_info_lbl.setObjectName("installed_version_info_lbl")
- self.overlay_info_layout.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.installed_version_info_lbl)
- self.installed_version_lbl = QtWidgets.QLabel(self.overlay_info_page)
- self.installed_version_lbl.setText("error")
- self.installed_version_lbl.setObjectName("installed_version_lbl")
- self.overlay_info_layout.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.installed_version_lbl)
- self.installed_path_info_lbl = QtWidgets.QLabel(self.overlay_info_page)
- self.installed_path_info_lbl.setObjectName("installed_path_info_lbl")
- self.overlay_info_layout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.installed_path_info_lbl)
- self.installed_path_lbl = QtWidgets.QLabel(self.overlay_info_page)
- self.installed_path_lbl.setText("error")
- self.installed_path_lbl.setObjectName("installed_path_lbl")
- self.overlay_info_layout.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.installed_path_lbl)
- self.info_buttons_layout = QtWidgets.QHBoxLayout()
- self.info_buttons_layout.setObjectName("info_buttons_layout")
- spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
- self.info_buttons_layout.addItem(spacerItem)
- self.uninstall_button = QtWidgets.QPushButton(self.overlay_info_page)
- self.uninstall_button.setMinimumSize(QtCore.QSize(120, 0))
- self.uninstall_button.setObjectName("uninstall_button")
- self.info_buttons_layout.addWidget(self.uninstall_button)
- self.update_check_button = QtWidgets.QPushButton(self.overlay_info_page)
- self.update_check_button.setMinimumSize(QtCore.QSize(120, 0))
- self.update_check_button.setObjectName("update_check_button")
- self.info_buttons_layout.addWidget(self.update_check_button)
- self.update_button = QtWidgets.QPushButton(self.overlay_info_page)
- self.update_button.setMinimumSize(QtCore.QSize(120, 0))
- self.update_button.setObjectName("update_button")
- self.info_buttons_layout.addWidget(self.update_button)
- self.overlay_info_layout.setLayout(3, QtWidgets.QFormLayout.SpanningRole, self.info_buttons_layout)
- spacerItem1 = QtWidgets.QSpacerItem(6, 6, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
- self.overlay_info_layout.setItem(2, QtWidgets.QFormLayout.SpanningRole, spacerItem1)
- self.overlay_stack.addWidget(self.overlay_info_page)
- self.overlay_install_page = QtWidgets.QWidget()
- self.overlay_install_page.setObjectName("overlay_install_page")
- self.overlay_install_layout = QtWidgets.QFormLayout(self.overlay_install_page)
- self.overlay_install_layout.setLabelAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
- self.overlay_install_layout.setFormAlignment(QtCore.Qt.AlignBottom|QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft)
- self.overlay_install_layout.setObjectName("overlay_install_layout")
- self.label = QtWidgets.QLabel(self.overlay_install_page)
- self.label.setObjectName("label")
- self.overlay_install_layout.setWidget(0, QtWidgets.QFormLayout.SpanningRole, self.label)
- self.install_buttons_layout = QtWidgets.QHBoxLayout()
- self.install_buttons_layout.setObjectName("install_buttons_layout")
- spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
- self.install_buttons_layout.addItem(spacerItem2)
- self.install_button = QtWidgets.QPushButton(self.overlay_install_page)
- self.install_button.setMinimumSize(QtCore.QSize(120, 0))
+ self.install_page = QtWidgets.QWidget()
+ self.install_page.setObjectName("install_page")
+ self.install_page_layout = QtWidgets.QHBoxLayout(self.install_page)
+ self.install_page_layout.setContentsMargins(0, 0, 0, 0)
+ self.install_page_layout.setObjectName("install_page_layout")
+ self.install_label_layout = QtWidgets.QFormLayout()
+ self.install_label_layout.setLabelAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
+ self.install_label_layout.setFormAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter)
+ self.install_label_layout.setObjectName("install_label_layout")
+ self.install_label = QtWidgets.QLabel(self.install_page)
+ self.install_label.setObjectName("install_label")
+ self.install_label_layout.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.install_label)
+ self.install_text = QtWidgets.QLabel(self.install_page)
+ self.install_text.setObjectName("install_text")
+ self.install_label_layout.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.install_text)
+ self.install_page_layout.addLayout(self.install_label_layout)
+ self.install_button_layout = QtWidgets.QVBoxLayout()
+ self.install_button_layout.setContentsMargins(-1, -1, 0, -1)
+ self.install_button_layout.setObjectName("install_button_layout")
+ self.install_button = QtWidgets.QPushButton(self.install_page)
+ self.install_button.setMinimumSize(QtCore.QSize(140, 0))
self.install_button.setObjectName("install_button")
- self.install_buttons_layout.addWidget(self.install_button)
- self.overlay_install_layout.setLayout(2, QtWidgets.QFormLayout.SpanningRole, self.install_buttons_layout)
- spacerItem3 = QtWidgets.QSpacerItem(6, 6, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
- self.overlay_install_layout.setItem(1, QtWidgets.QFormLayout.SpanningRole, spacerItem3)
- self.overlay_stack.addWidget(self.overlay_install_page)
+ self.install_button_layout.addWidget(self.install_button)
+ self.install_page_layout.addLayout(self.install_button_layout)
+ self.install_page_layout.setStretch(0, 1)
+ self.overlay_stack.addWidget(self.install_page)
+ self.info_page = QtWidgets.QWidget()
+ self.info_page.setObjectName("info_page")
+ self.info_page_layout = QtWidgets.QHBoxLayout(self.info_page)
+ self.info_page_layout.setContentsMargins(0, 0, 0, 0)
+ self.info_page_layout.setObjectName("info_page_layout")
+ self.info_label_layout = QtWidgets.QFormLayout()
+ self.info_label_layout.setLabelAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
+ self.info_label_layout.setFormAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter)
+ self.info_label_layout.setObjectName("info_label_layout")
+ self.version_label = QtWidgets.QLabel(self.info_page)
+ self.version_label.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
+ self.version_label.setObjectName("version_label")
+ self.info_label_layout.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.version_label)
+ self.path_label = QtWidgets.QLabel(self.info_page)
+ self.path_label.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
+ self.path_label.setObjectName("path_label")
+ self.info_label_layout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.path_label)
+ self.info_page_layout.addLayout(self.info_label_layout)
+ self.info_button_layout = QtWidgets.QVBoxLayout()
+ self.info_button_layout.setObjectName("info_button_layout")
+ self.update_button = QtWidgets.QPushButton(self.info_page)
+ self.update_button.setMinimumSize(QtCore.QSize(140, 0))
+ self.update_button.setObjectName("update_button")
+ self.info_button_layout.addWidget(self.update_button)
+ self.uninstall_button = QtWidgets.QPushButton(self.info_page)
+ self.uninstall_button.setMinimumSize(QtCore.QSize(140, 0))
+ self.uninstall_button.setObjectName("uninstall_button")
+ self.info_button_layout.addWidget(self.uninstall_button)
+ self.info_page_layout.addLayout(self.info_button_layout)
+ self.info_page_layout.setStretch(0, 1)
+ self.overlay_stack.addWidget(self.info_page)
self.eos_layout.addWidget(self.overlay_stack)
- self.enable_frame = QtWidgets.QFrame(EosWidget)
- self.enable_frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
- self.enable_frame.setFrameShadow(QtWidgets.QFrame.Raised)
- self.enable_frame.setObjectName("enable_frame")
- self.enable_layout = QtWidgets.QVBoxLayout(self.enable_frame)
- self.enable_layout.setObjectName("enable_layout")
- self.select_pfx_combo = QtWidgets.QComboBox(self.enable_frame)
- self.select_pfx_combo.setObjectName("select_pfx_combo")
- self.enable_layout.addWidget(self.select_pfx_combo)
- self.enabled_cb = QtWidgets.QCheckBox(self.enable_frame)
- self.enabled_cb.setObjectName("enabled_cb")
- self.enable_layout.addWidget(self.enabled_cb)
- self.enabled_info_label = QtWidgets.QLabel(self.enable_frame)
- font = QtGui.QFont()
- font.setItalic(True)
- self.enabled_info_label.setFont(font)
- self.enabled_info_label.setText("")
- self.enabled_info_label.setObjectName("enabled_info_label")
- self.enable_layout.addWidget(self.enabled_info_label)
- self.eos_layout.addWidget(self.enable_frame)
self.retranslateUi(EosWidget)
self.overlay_stack.setCurrentIndex(0)
@@ -117,14 +86,13 @@ class Ui_EosWidget(object):
def retranslateUi(self, EosWidget):
_translate = QtCore.QCoreApplication.translate
EosWidget.setTitle(_translate("EosWidget", "Epic Overlay"))
- self.installed_version_info_lbl.setText(_translate("EosWidget", "Version"))
- self.installed_path_info_lbl.setText(_translate("EosWidget", "Location"))
- self.uninstall_button.setText(_translate("EosWidget", "Uninstall"))
- self.update_check_button.setText(_translate("EosWidget", "Check for update"))
- self.update_button.setText(_translate("EosWidget", "Update"))
- self.label.setText(_translate("EosWidget", "Epic Overlay Services is not installed"))
+ self.install_label.setText(_translate("EosWidget", "Status:"))
+ self.install_text.setText(_translate("EosWidget", "Epic Online Services Overlay is not installed"))
self.install_button.setText(_translate("EosWidget", "Install"))
- self.enabled_cb.setText(_translate("EosWidget", "Activated"))
+ self.version_label.setText(_translate("EosWidget", "Version:"))
+ self.path_label.setText(_translate("EosWidget", "Path:"))
+ self.update_button.setText(_translate("EosWidget", "Update"))
+ self.uninstall_button.setText(_translate("EosWidget", "Uninstall"))
if __name__ == "__main__":
diff --git a/rare/ui/components/tabs/games/integrations/eos_widget.ui b/rare/ui/components/tabs/games/integrations/eos_widget.ui
index 84e017bf..81dad003 100644
--- a/rare/ui/components/tabs/games/integrations/eos_widget.ui
+++ b/rare/ui/components/tabs/games/integrations/eos_widget.ui
@@ -6,179 +6,73 @@
0
0
- 586
- 146
+ 464
+ 98
-
-
- 0
- 0
-
-
GroupBox
Epic Overlay
-
+
QLayout::SetDefaultConstraint
-
-
- QFrame::StyledPanel
-
-
- QFrame::Raised
-
0
-
-
-
- Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ 0
-
- Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft
+
+ 0
-
-
-
-
- Version
+
+ 0
+
+
+ 0
+
+
-
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
-
- -
-
-
- error
+
+ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter
-
-
- -
-
-
- Location
-
-
-
- -
-
-
- error
-
-
-
- -
-
-
-
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
- -
-
-
-
- 120
- 0
-
-
+
-
+
- Uninstall
+ Status:
- -
-
-
-
- 120
- 0
-
-
+
-
+
- Check for update
-
-
-
- -
-
-
-
- 120
- 0
-
-
-
- Update
+ Epic Online Services Overlay is not installed
- -
-
-
- Qt::Vertical
+
-
+
+
+ 0
-
-
- 6
- 6
-
-
-
-
-
-
-
-
-
- Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
-
- Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft
-
- -
-
-
- Epic Overlay Services is not installed
-
-
-
- -
-
-
-
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
-
- 120
+ 140
0
@@ -189,57 +83,86 @@
- -
-
-
- Qt::Vertical
+
+
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
-
- 6
- 6
-
+
+ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter
-
+
-
+
+
+ Version:
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+ -
+
+
+ Path:
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+
+
+
+ -
+
+
-
+
+
+
+ 140
+ 0
+
+
+
+ Update
+
+
+
+ -
+
+
+
+ 140
+ 0
+
+
+
+ Uninstall
+
+
+
+
- -
-
-
- QFrame::StyledPanel
-
-
- QFrame::Raised
-
-
-
-
-
-
- -
-
-
- Activated
-
-
-
- -
-
-
-
- true
-
-
-
-
-
-
-
-
-
-