UninstallDialog: add option to keep the game's folder
previously, if the game's install directory had remaining untracked data, it would not get deleted. this option force-deletes it it is not checked.
This commit is contained in:
parent
c7436700fd
commit
b5901c5a6d
5 changed files with 52 additions and 44 deletions
|
@ -1,4 +1,4 @@
|
|||
from PyQt5.QtCore import pyqtSignal
|
||||
from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot
|
||||
from PyQt5.QtWidgets import (
|
||||
QVBoxLayout,
|
||||
QCheckBox,
|
||||
|
@ -23,6 +23,10 @@ class UninstallDialog(ButtonDialog):
|
|||
self.keep_files.setChecked(bool(options.keep_files))
|
||||
self.keep_files.setEnabled(not rgame.is_overlay)
|
||||
|
||||
self.keep_folder = QCheckBox(self.tr("Keep game folder"))
|
||||
self.keep_folder.setChecked(bool(options.keep_folder))
|
||||
self.keep_folder.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)
|
||||
|
@ -33,6 +37,7 @@ class UninstallDialog(ButtonDialog):
|
|||
|
||||
layout = QVBoxLayout()
|
||||
layout.addWidget(self.keep_files)
|
||||
layout.addWidget(self.keep_folder)
|
||||
layout.addWidget(self.keep_config)
|
||||
layout.addWidget(self.keep_overlay_keys)
|
||||
|
||||
|
@ -42,21 +47,25 @@ class UninstallDialog(ButtonDialog):
|
|||
self.accept_button.setIcon(qta_icon("ri.uninstall-line"))
|
||||
self.accept_button.setObjectName("UninstallButton")
|
||||
|
||||
if rgame.sdl_name is not None:
|
||||
self.keep_config.setChecked(True)
|
||||
self.keep_files.stateChanged.connect(self.__on_keep_files_changed)
|
||||
|
||||
self.options: UninstallOptionsModel = options
|
||||
|
||||
@pyqtSlot(int)
|
||||
def __on_keep_files_changed(self, state: int):
|
||||
self.keep_folder.setCheckState(state if state else Qt.Checked)
|
||||
self.keep_folder.setEnabled(not state)
|
||||
|
||||
def done_handler(self) -> None:
|
||||
self.result_ready.emit(self.options)
|
||||
|
||||
def accept_handler(self):
|
||||
self.options.values = (
|
||||
True,
|
||||
self.keep_files.isChecked(),
|
||||
self.keep_config.isChecked(),
|
||||
self.keep_overlay_keys.isChecked(),
|
||||
self.options.set_accepted(
|
||||
keep_files=self.keep_files.isChecked(),
|
||||
keep_folder=self.keep_folder.isChecked(),
|
||||
keep_config=self.keep_config.isChecked(),
|
||||
keep_overlay_keys=self.keep_overlay_keys.isChecked(),
|
||||
)
|
||||
|
||||
def reject_handler(self):
|
||||
self.options.values = (None, None, None, None)
|
||||
self.options.set_rejected()
|
||||
|
|
|
@ -352,7 +352,6 @@ class DownloadsTab(QWidget):
|
|||
def __on_uninstall_dialog_closed(self, options: UninstallOptionsModel):
|
||||
rgame = self.rcore.get_game(options.app_name)
|
||||
if options and options.accepted:
|
||||
rgame.set_installed(False)
|
||||
worker = UninstallWorker(self.core, rgame, options)
|
||||
worker.signals.result.connect(self.__on_uninstall_worker_result)
|
||||
QThreadPool.globalInstance().start(worker)
|
||||
|
@ -361,6 +360,8 @@ class DownloadsTab(QWidget):
|
|||
|
||||
@pyqtSlot(RareGame, bool, str)
|
||||
def __on_uninstall_worker_result(self, rgame: RareGame, success: bool, message: str):
|
||||
if not success:
|
||||
if success:
|
||||
rgame.set_installed(False)
|
||||
else:
|
||||
QMessageBox.warning(None, self.tr("Uninstall - {}").format(rgame.app_title), message, QMessageBox.Close)
|
||||
rgame.state = RareGame.State.IDLE
|
||||
|
|
|
@ -555,7 +555,7 @@ class RareGame(RareGameSlim):
|
|||
if not self.is_idle:
|
||||
return False
|
||||
self.signals.game.uninstall.emit(
|
||||
UninstallOptionsModel(app_name=self.app_name)
|
||||
UninstallOptionsModel(app_name=self.app_name, keep_config=self.sdl_name is not None)
|
||||
)
|
||||
return True
|
||||
|
||||
|
|
|
@ -85,41 +85,29 @@ class UninstallOptionsModel:
|
|||
app_name: str
|
||||
accepted: bool = None
|
||||
keep_files: bool = None
|
||||
keep_folder: bool = True
|
||||
keep_config: bool = None
|
||||
keep_overlay_keys: bool = None
|
||||
|
||||
def __bool__(self):
|
||||
return (
|
||||
bool(self.app_name)
|
||||
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, bool]:
|
||||
"""
|
||||
This model's options
|
||||
def __values(self) -> Tuple[bool, bool, bool, bool, bool]:
|
||||
return self.accepted, self.keep_config, self.keep_folder, self.keep_files, self.keep_overlay_keys
|
||||
|
||||
:return:
|
||||
Tuple of `accepted` `keep_files` `keep_config` `keep_overlay_keys`
|
||||
"""
|
||||
return self.accepted, self.keep_config, self.keep_files, self.keep_overlay_keys
|
||||
@__values.setter
|
||||
def __values(self, values: Tuple[bool, bool, bool, bool, bool]):
|
||||
self.accepted, self.keep_files, self.keep_folder, self.keep_config, self.keep_overlay_keys = values
|
||||
|
||||
@values.setter
|
||||
def values(self, values: Tuple[bool, bool, bool, bool]):
|
||||
"""
|
||||
Set this model's options
|
||||
def __bool__(self):
|
||||
return bool(self.app_name) and all(map(lambda x: x is not None, self.__values))
|
||||
|
||||
:param values:
|
||||
Tuple of `accepted` `keep_files` `keep_config` `keep_overlay_keys`
|
||||
:return:
|
||||
"""
|
||||
self.accepted = values[0]
|
||||
self.keep_files = values[1]
|
||||
self.keep_config = values[2]
|
||||
self.keep_overlay_keys = values[3]
|
||||
def __iter__(self):
|
||||
return iter(self.__values)
|
||||
|
||||
def set_accepted(self, keep_config, keep_folder, keep_files, keep_overlay_keys):
|
||||
self.__values = True, keep_config, keep_folder, keep_files, keep_overlay_keys
|
||||
|
||||
def set_rejected(self):
|
||||
self.__values = False, None, None, None, None
|
||||
|
||||
|
||||
@dataclass
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import platform
|
||||
import shutil
|
||||
from logging import getLogger
|
||||
from typing import Tuple
|
||||
|
||||
|
@ -20,7 +21,7 @@ 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, rgame: RareGame, keep_files=False, keep_config=False, keep_overlay_keys=False
|
||||
core: LegendaryCore, rgame: RareGame, keep_files=False, keep_folder=True, keep_config=False, keep_overlay_keys=False
|
||||
) -> Tuple[bool, str]:
|
||||
if rgame.is_overlay:
|
||||
logger.info('Deleting overlay installation...')
|
||||
|
@ -53,6 +54,8 @@ def uninstall_game(
|
|||
if link_path.exists():
|
||||
link_path.unlink(missing_ok=True)
|
||||
|
||||
install_path = rgame.igame.install_path
|
||||
|
||||
status = LgndrIndirectStatus()
|
||||
LegendaryCLI(core).uninstall_game(
|
||||
LgndrUninstallGameArgs(
|
||||
|
@ -63,6 +66,12 @@ def uninstall_game(
|
|||
indirect_status=status,
|
||||
)
|
||||
)
|
||||
|
||||
keep_folder = keep_files if keep_files else keep_folder
|
||||
if not keep_folder:
|
||||
logger.info("Removing game install directory")
|
||||
shutil.rmtree(install_path, ignore_errors=True)
|
||||
|
||||
if not keep_config:
|
||||
logger.info("Removing sections in config file")
|
||||
config.remove_section(rgame.app_name)
|
||||
|
@ -89,9 +98,10 @@ class UninstallWorker(Worker):
|
|||
success, message = uninstall_game(
|
||||
self.core,
|
||||
self.rgame,
|
||||
self.options.keep_files,
|
||||
self.options.keep_config,
|
||||
self.options.keep_overlay_keys,
|
||||
keep_files=self.options.keep_files,
|
||||
keep_folder=self.options.keep_folder,
|
||||
keep_config=self.options.keep_config,
|
||||
keep_overlay_keys=self.options.keep_overlay_keys,
|
||||
)
|
||||
self.rgame.state = RareGame.State.IDLE
|
||||
self.signals.result.emit(self.rgame, success, message)
|
||||
|
|
Loading…
Reference in a new issue