MoveDialog: Refactor MovePopup into a dialog using ActionDialog as base
This commit is contained in:
parent
17a5562b4c
commit
0fb1526d67
|
@ -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()
|
||||
|
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in a new issue