1
0
Fork 0
mirror of synced 2024-05-18 19:42:54 +12:00

MoveDialog: Refactor MovePopup into a dialog using ActionDialog as base

This commit is contained in:
loathingKernel 2024-01-02 23:11:47 +02:00
parent 17a5562b4c
commit 0fb1526d67
5 changed files with 82 additions and 69 deletions

View file

@ -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"<h4>{dialog_title_game(header, rgame.app_title)}</h4>", 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 <b>{}</b>").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()

View file

@ -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()

View file

@ -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)
)

View file

@ -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)

View file

@ -488,7 +488,7 @@
<number>0</number>
</property>
<item>
<widget class="QToolButton" name="move_button">
<widget class="QPushButton" name="move_button">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
@ -498,15 +498,6 @@
<property name="text">
<string>Move</string>
</property>
<property name="popupMode">
<enum>QToolButton::InstantPopup</enum>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextOnly</enum>
</property>
<property name="arrowType">
<enum>Qt::DownArrow</enum>
</property>
</widget>
</item>
</layout>