From 0fb1526d67f714b59fbb30458cd8d5dcd6586cd3 Mon Sep 17 00:00:00 2001
From: loathingKernel <142770+loathingKernel@users.noreply.github.com>
Date: Tue, 2 Jan 2024 23:11:47 +0200
Subject: [PATCH] MoveDialog: Refactor MovePopup into a dialog using
ActionDialog as base
---
.../move_game.py => dialogs/move_dialog.py} | 79 ++++++++++++-------
.../tabs/games/game_info/game_info.py | 39 ++++-----
rare/models/install.py | 17 +++-
.../tabs/games/game_info/game_info.py | 5 +-
.../tabs/games/game_info/game_info.ui | 11 +--
5 files changed, 82 insertions(+), 69 deletions(-)
rename rare/components/{tabs/games/game_info/move_game.py => dialogs/move_dialog.py} (76%)
diff --git a/rare/components/tabs/games/game_info/move_game.py b/rare/components/dialogs/move_dialog.py
similarity index 76%
rename from rare/components/tabs/games/game_info/move_game.py
rename to rare/components/dialogs/move_dialog.py
index 37ebebac..cab68049 100644
--- a/rare/components/tabs/games/game_info/move_game.py
+++ b/rare/components/dialogs/move_dialog.py
@@ -4,12 +4,14 @@ from enum import auto
from logging import getLogger
from typing import Tuple, Optional
-from PyQt5.QtCore import pyqtSignal, Qt, pyqtSlot
-from PyQt5.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLabel, QFileDialog
+from PyQt5.QtCore import pyqtSignal, pyqtSlot
+from PyQt5.QtWidgets import QVBoxLayout, QHBoxLayout, QLabel, QFileDialog, QLayout
+from rare.models.install import MoveGameModel
from rare.models.game import RareGame
from rare.shared import RareCore
-from rare.utils.misc import path_size, format_size
+from rare.utils.misc import path_size, format_size, icon
+from rare.widgets.dialogs import ActionDialog, dialog_title_game
from rare.widgets.elide_label import ElideLabel
from rare.widgets.indicator_edit import PathEdit, IndicatorReasons, IndicatorReasonsCommon
@@ -25,12 +27,16 @@ class MovePathEditReasons(IndicatorReasons):
NO_SPACE = auto()
-class MoveGamePopUp(QWidget):
- move_clicked = pyqtSignal(str)
- browse_done = pyqtSignal()
+class MoveDialog(ActionDialog):
+ result_ready = pyqtSignal(RareGame, MoveGameModel)
+
+ def __init__(self, rgame: RareGame, parent=None):
+ super(MoveDialog, self).__init__(parent=parent)
+ header = self.tr("Move")
+ self.setWindowTitle(dialog_title_game(header, rgame.app_title))
+
+ title_label = QLabel(f"
{dialog_title_game(header, rgame.app_title)}
", self)
- def __init__(self, parent=None):
- super(MoveGamePopUp, self).__init__(parent=parent)
self.rcore = RareCore.instance()
self.core = RareCore.instance().core()
self.rgame: Optional[RareGame] = None
@@ -44,19 +50,9 @@ class MoveGamePopUp(QWidget):
MovePathEditReasons.NESTED_DIR: self.tr("Game install directories cannot be nested."),
MovePathEditReasons.NO_SPACE: self.tr("Not enough space available on drive."),
})
- self.path_edit.path_select.clicked.connect(self.browse_done)
-
- self.button = QPushButton(self.tr("Move"))
- self.button.setFixedSize(self.path_edit.path_select.sizeHint())
- self.button.clicked.connect(lambda p: self.move_clicked.emit(self.path_edit.text()))
self.warn_label = ElideLabel("", parent=self)
- middle_layout = QHBoxLayout()
- middle_layout.setAlignment(Qt.AlignRight)
- middle_layout.addWidget(self.warn_label, stretch=1)
- middle_layout.addWidget(self.button)
-
font = self.font()
font.setBold(True)
self.req_space_label = QLabel(self.tr("Required:"), self)
@@ -72,11 +68,38 @@ class MoveGamePopUp(QWidget):
bottom_layout.addWidget(self.avail_space_label)
bottom_layout.addWidget(self.avail_space, stretch=1)
- layout: QVBoxLayout = QVBoxLayout(self)
+ layout = QVBoxLayout()
+ layout.setSizeConstraint(QLayout.SetFixedSize)
+ layout.addWidget(title_label)
layout.addWidget(self.path_edit)
- layout.addLayout(middle_layout)
+ layout.addWidget(self.warn_label)
layout.addLayout(bottom_layout)
+ self.setCentralLayout(layout)
+
+ self.accept_button.setText(self.tr("Move"))
+ self.accept_button.setIcon(icon("mdi.folder-move-outline"))
+
+ self.action_button.setHidden(True)
+
+ self.update_game(rgame)
+
+ self.options: MoveGameModel = MoveGameModel(rgame.app_name)
+
+ def action_handler(self):
+ pass
+
+ def done_handler(self):
+ self.result_ready.emit(self.rgame, self.options)
+
+ def accept_handler(self):
+ self.options.accepted = True
+ self.options.target_path = self.path_edit.text()
+
+ def reject_handler(self):
+ self.options.accepted = False
+ self.options.target_path = ""
+
def refresh_indicator(self):
# needed so the edit_func gets run again
text = self.path_edit.text()
@@ -84,13 +107,13 @@ class MoveGamePopUp(QWidget):
self.path_edit.setText(text)
def path_edit_callback(self, path: str) -> Tuple[bool, str, int]:
- self.button.setEnabled(True)
+ self.accept_button.setEnabled(True)
self.warn_label.setHidden(False)
self.req_space.setText("...")
self.avail_space.setText("...")
def helper_func(reason: int) -> Tuple[bool, str, int]:
- self.button.setEnabled(False)
+ self.accept_button.setEnabled(False)
return False, path, reason
if not self.rgame.install_path or not path:
@@ -141,7 +164,7 @@ class MoveGamePopUp(QWidget):
return helper_func(MovePathEditReasons.NO_SPACE)
# Fallback
- self.button.setEnabled(True)
+ self.accept_button.setEnabled(True)
return True, path, IndicatorReasonsCommon.VALID
@pyqtSlot()
@@ -151,20 +174,18 @@ class MoveGamePopUp(QWidget):
self.setDisabled(True)
return
# FIXME: Make edit_func lighter instead of blocking signals
- self.path_edit.line_edit.blockSignals(True)
+ # self.path_edit.line_edit.blockSignals(True)
+ self.setActive(True)
self.path_edit.setText(self.rgame.install_path)
# FIXME: Make edit_func lighter instead of blocking signals
- self.path_edit.line_edit.blockSignals(False)
+ # self.path_edit.line_edit.blockSignals(False)
+ self.setActive(False)
self.warn_label.setText(
self.tr("Moving here will overwrite {}").format(os.path.basename(self.rgame.install_path))
)
self.refresh_indicator()
def update_game(self, rgame: RareGame):
- if self.rgame is not None:
- self.rgame.signals.widget.update.disconnect(self.__update_widget)
- self.rgame = None
- rgame.signals.widget.update.connect(self.__update_widget)
self.rgame = rgame
self.__update_widget()
diff --git a/rare/components/tabs/games/game_info/game_info.py b/rare/components/tabs/games/game_info/game_info.py
index aed40fea..16030470 100644
--- a/rare/components/tabs/games/game_info/game_info.py
+++ b/rare/components/tabs/games/game_info/game_info.py
@@ -10,13 +10,11 @@ from PyQt5.QtCore import (
pyqtSignal,
)
from PyQt5.QtWidgets import (
- QMenu,
QWidget,
QMessageBox,
- QWidgetAction,
)
-from rare.models.install import SelectiveDownloadsModel
+from rare.models.install import SelectiveDownloadsModel, MoveGameModel
from rare.components.dialogs.selective_dialog import SelectiveDialog
from rare.models.game import RareGame
from rare.shared import RareCore
@@ -25,7 +23,7 @@ from rare.ui.components.tabs.games.game_info.game_info import Ui_GameInfo
from rare.utils.misc import format_size, icon
from rare.widgets.image_widget import ImageWidget, ImageSize
from rare.widgets.side_tab import SideTabContents
-from .move_game import MoveGamePopUp, is_game_dir
+from rare.components.dialogs.move_dialog import MoveDialog, is_game_dir
logger = getLogger("GameInfo")
@@ -68,18 +66,9 @@ class GameInfo(QWidget, SideTabContents):
self.ui.modify_button.clicked.connect(self.__on_modify)
self.ui.verify_button.clicked.connect(self.__on_verify)
self.ui.repair_button.clicked.connect(self.__on_repair)
+ self.ui.move_button.clicked.connect(self.__on_move)
self.ui.uninstall_button.clicked.connect(self.__on_uninstall)
- self.move_game_pop_up = MoveGamePopUp(self)
- move_action = QWidgetAction(self)
- move_action.setDefaultWidget(self.move_game_pop_up)
- self.ui.move_button.setMenu(QMenu(self.ui.move_button))
- self.ui.move_button.menu().addAction(move_action)
-
- self.move_game_pop_up.browse_done.connect(self.ui.move_button.showMenu)
- self.move_game_pop_up.move_clicked.connect(self.ui.move_button.menu().close)
- self.move_game_pop_up.move_clicked.connect(self.__on_move)
-
self.steam_grade_ratings = {
"platinum": self.tr("Platinum"),
"gold": self.tr("Gold"),
@@ -217,17 +206,24 @@ class GameInfo(QWidget, SideTabContents):
if ans == QMessageBox.Yes:
self.repair_game(rgame)
- @pyqtSlot(str)
- def __on_move(self, dst_path: str):
+ @pyqtSlot()
+ def __on_move(self):
""" This method is to be called from the button only """
- new_install_path = os.path.join(dst_path, os.path.basename(self.rgame.install_path))
+ move_dialog = MoveDialog(self.rgame, parent=self)
+ move_dialog.result_ready.connect(self.move_game)
+ move_dialog.open()
+ def move_game(self, rgame: RareGame, model: MoveGameModel):
+ if not model.accepted:
+ return
+
+ new_install_path = os.path.join(model.target_path, os.path.basename(self.rgame.install_path))
dir_exists = False
if os.path.isdir(new_install_path):
dir_exists = is_game_dir(self.rgame.install_path, new_install_path)
if not dir_exists:
- for item in os.listdir(dst_path):
+ for item in os.listdir(model.target_path):
if os.path.basename(self.rgame.install_path) in os.path.basename(item):
ans = QMessageBox.question(
self,
@@ -248,11 +244,8 @@ class GameInfo(QWidget, SideTabContents):
else:
return
- self.move_game(self.rgame, new_install_path, dir_exists)
-
- def move_game(self, rgame: RareGame, dst_path, dst_exists):
worker = MoveWorker(
- self.core, rgame=rgame, dst_path=dst_path, dst_exists=dst_exists
+ self.core, rgame=rgame, dst_path=model.target_path, dst_exists=dir_exists
)
worker.signals.progress.connect(self.__on_move_progress)
worker.signals.result.connect(self.__on_move_result)
@@ -395,7 +388,5 @@ class GameInfo(QWidget, SideTabContents):
else:
self.ui.install_button.setText(self.tr("Install"))
- self.move_game_pop_up.update_game(rgame)
-
self.rgame = rgame
self.__update_widget()
diff --git a/rare/models/install.py b/rare/models/install.py
index 05ef39ef..69123d0b 100644
--- a/rare/models/install.py
+++ b/rare/models/install.py
@@ -101,7 +101,7 @@ class UninstallOptionsModel:
This model's options
:return:
- Tuple of `accepted` `keep_files` `keep_config`
+ Tuple of `accepted` `keep_files` `keep_config` `keep_overlay_keys`
"""
return self.accepted, self.keep_config, self.keep_files
@@ -111,7 +111,7 @@ class UninstallOptionsModel:
Set this model's options
:param values:
- Tuple of `accepted` `keep_files` `keep_config`
+ Tuple of `accepted` `keep_files` `keep_config` `keep_overlay_keys`
:return:
"""
self.accepted = values[0]
@@ -132,3 +132,16 @@ class SelectiveDownloadsModel:
and (self.install_tag is not None)
)
+
+@dataclass
+class MoveGameModel:
+ app_name: str
+ accepted: bool = None
+ target_path: Optional[str] = None
+
+ def __bool__(self):
+ return (
+ bool(self.app_name)
+ and (self.accepted is not None)
+ and (self.target_path is not None)
+ )
diff --git a/rare/ui/components/tabs/games/game_info/game_info.py b/rare/ui/components/tabs/games/game_info/game_info.py
index bce4a9d5..3457e942 100644
--- a/rare/ui/components/tabs/games/game_info/game_info.py
+++ b/rare/ui/components/tabs/games/game_info/game_info.py
@@ -255,15 +255,12 @@ class Ui_GameInfo(object):
self.move_button_layout.setContentsMargins(0, 0, 0, 0)
self.move_button_layout.setSpacing(0)
self.move_button_layout.setObjectName("move_button_layout")
- self.move_button = QtWidgets.QToolButton(self.move_button_page)
+ self.move_button = QtWidgets.QPushButton(self.move_button_page)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.move_button.sizePolicy().hasHeightForWidth())
self.move_button.setSizePolicy(sizePolicy)
- self.move_button.setPopupMode(QtWidgets.QToolButton.InstantPopup)
- self.move_button.setToolButtonStyle(QtCore.Qt.ToolButtonTextOnly)
- self.move_button.setArrowType(QtCore.Qt.DownArrow)
self.move_button.setObjectName("move_button")
self.move_button_layout.addWidget(self.move_button)
self.move_stack.addWidget(self.move_button_page)
diff --git a/rare/ui/components/tabs/games/game_info/game_info.ui b/rare/ui/components/tabs/games/game_info/game_info.ui
index 64796002..89115667 100644
--- a/rare/ui/components/tabs/games/game_info/game_info.ui
+++ b/rare/ui/components/tabs/games/game_info/game_info.ui
@@ -488,7 +488,7 @@
0
-
-
+
0
@@ -498,15 +498,6 @@
Move
-
- QToolButton::InstantPopup
-
-
- Qt::ToolButtonTextOnly
-
-
- Qt::DownArrow
-