Merge pull request #352 from loathingKernel/next
Preparation for future features
This commit is contained in:
commit
826d38ca55
|
@ -76,14 +76,15 @@ class Rare(RareApp):
|
||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
def launch_app(self):
|
def launch_app(self):
|
||||||
self.launch_dialog = LaunchDialog(parent=None)
|
self.launch_dialog = LaunchDialog(parent=None)
|
||||||
self.launch_dialog.exit_app.connect(self.launch_dialog.close)
|
self.launch_dialog.rejected.connect(self.__on_exit_app)
|
||||||
self.launch_dialog.exit_app.connect(self.__on_exit_app)
|
# lk: the reason we use the `start_app` signal here instead of accepted, is to keep the dialog
|
||||||
self.launch_dialog.start_app.connect(self.start_app)
|
# until the main window has been created, then we call `accept()` to close the dialog
|
||||||
self.launch_dialog.start_app.connect(self.launch_dialog.close)
|
self.launch_dialog.start_app.connect(self.__on_start_app)
|
||||||
|
self.launch_dialog.start_app.connect(self.launch_dialog.accept)
|
||||||
self.launch_dialog.login()
|
self.launch_dialog.login()
|
||||||
|
|
||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
def start_app(self):
|
def __on_start_app(self):
|
||||||
self.timer = QTimer()
|
self.timer = QTimer()
|
||||||
self.timer.timeout.connect(self.re_login)
|
self.timer.timeout.connect(self.re_login)
|
||||||
self.poke_timer()
|
self.poke_timer()
|
||||||
|
|
|
@ -1,25 +1,24 @@
|
||||||
import platform
|
|
||||||
from logging import getLogger
|
from logging import getLogger
|
||||||
|
|
||||||
from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot
|
from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot
|
||||||
from PyQt5.QtWidgets import QDialog, QApplication
|
|
||||||
from requests.exceptions import ConnectionError, HTTPError
|
from requests.exceptions import ConnectionError, HTTPError
|
||||||
|
|
||||||
from rare.components.dialogs.login import LoginDialog
|
from rare.components.dialogs.login import LoginDialog
|
||||||
from rare.shared import RareCore
|
from rare.shared import RareCore
|
||||||
from rare.ui.components.dialogs.launch_dialog import Ui_LaunchDialog
|
from rare.ui.components.dialogs.launch_dialog import Ui_LaunchDialog
|
||||||
|
from rare.widgets.dialogs import BaseDialog
|
||||||
from rare.widgets.elide_label import ElideLabel
|
from rare.widgets.elide_label import ElideLabel
|
||||||
|
|
||||||
logger = getLogger("LaunchDialog")
|
logger = getLogger("LaunchDialog")
|
||||||
|
|
||||||
|
|
||||||
class LaunchDialog(QDialog):
|
class LaunchDialog(BaseDialog):
|
||||||
exit_app = pyqtSignal(int)
|
# lk: the reason we use the `start_app` signal here instead of accepted, is to keep the dialog
|
||||||
|
# until the main window has been created, then we call `accept()` to close the dialog
|
||||||
start_app = pyqtSignal()
|
start_app = pyqtSignal()
|
||||||
|
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
super(LaunchDialog, self).__init__(parent=parent)
|
super(LaunchDialog, self).__init__(parent=parent)
|
||||||
self.setAttribute(Qt.WA_DeleteOnClose, True)
|
|
||||||
self.setWindowFlags(
|
self.setWindowFlags(
|
||||||
Qt.Window
|
Qt.Window
|
||||||
| Qt.Dialog
|
| Qt.Dialog
|
||||||
|
@ -29,12 +28,10 @@ class LaunchDialog(QDialog):
|
||||||
| Qt.WindowMinimizeButtonHint
|
| Qt.WindowMinimizeButtonHint
|
||||||
| Qt.MSWindowsFixedSizeDialogHint
|
| Qt.MSWindowsFixedSizeDialogHint
|
||||||
)
|
)
|
||||||
self.setWindowModality(Qt.WindowModal)
|
|
||||||
self.ui = Ui_LaunchDialog()
|
self.ui = Ui_LaunchDialog()
|
||||||
self.ui.setupUi(self)
|
self.ui.setupUi(self)
|
||||||
|
|
||||||
self.reject_close = True
|
|
||||||
|
|
||||||
self.progress_info = ElideLabel(parent=self)
|
self.progress_info = ElideLabel(parent=self)
|
||||||
self.progress_info.setFixedHeight(False)
|
self.progress_info.setFixedHeight(False)
|
||||||
self.ui.launch_layout.addWidget(self.progress_info)
|
self.ui.launch_layout.addWidget(self.progress_info)
|
||||||
|
@ -46,9 +43,11 @@ class LaunchDialog(QDialog):
|
||||||
self.args = self.rcore.args()
|
self.args = self.rcore.args()
|
||||||
|
|
||||||
self.login_dialog = LoginDialog(core=self.core, parent=parent)
|
self.login_dialog = LoginDialog(core=self.core, parent=parent)
|
||||||
|
self.login_dialog.rejected.connect(self.reject)
|
||||||
|
self.login_dialog.accepted.connect(self.do_launch)
|
||||||
|
|
||||||
def login(self):
|
def login(self):
|
||||||
do_launch = True
|
can_launch = True
|
||||||
try:
|
try:
|
||||||
if self.args.offline:
|
if self.args.offline:
|
||||||
pass
|
pass
|
||||||
|
@ -56,25 +55,29 @@ class LaunchDialog(QDialog):
|
||||||
# Force an update check and notice in case there are API changes
|
# Force an update check and notice in case there are API changes
|
||||||
# self.core.check_for_updates(force=True)
|
# self.core.check_for_updates(force=True)
|
||||||
# self.core.force_show_update = True
|
# self.core.force_show_update = True
|
||||||
if self.core.login():
|
if self.core.login(force_refresh=True):
|
||||||
logger.info("You are logged in")
|
logger.info("You are logged in")
|
||||||
|
self.login_dialog.close()
|
||||||
else:
|
else:
|
||||||
raise ValueError("You are not logged in. Open Login Window")
|
raise ValueError("You are not logged in. Opening login window.")
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
logger.info(str(e))
|
logger.info(str(e))
|
||||||
# Do not set parent, because it won't show a task bar icon
|
# Do not set parent, because it won't show a task bar icon
|
||||||
# Update: Inherit the same parent as LaunchDialog
|
# Update: Inherit the same parent as LaunchDialog
|
||||||
do_launch = self.login_dialog.login()
|
can_launch = False
|
||||||
|
self.login_dialog.open()
|
||||||
except (HTTPError, ConnectionError) as e:
|
except (HTTPError, ConnectionError) as e:
|
||||||
logger.warning(e)
|
logger.warning(e)
|
||||||
self.args.offline = True
|
self.args.offline = True
|
||||||
finally:
|
finally:
|
||||||
if do_launch:
|
if can_launch:
|
||||||
if not self.args.silent:
|
self.do_launch()
|
||||||
self.show()
|
|
||||||
self.launch()
|
@pyqtSlot()
|
||||||
else:
|
def do_launch(self):
|
||||||
self.exit_app.emit(0)
|
if not self.args.silent:
|
||||||
|
self.open()
|
||||||
|
self.launch()
|
||||||
|
|
||||||
def launch(self):
|
def launch(self):
|
||||||
self.progress_info.setText(self.tr("Preparing Rare"))
|
self.progress_info.setText(self.tr("Preparing Rare"))
|
||||||
|
@ -87,9 +90,4 @@ class LaunchDialog(QDialog):
|
||||||
|
|
||||||
def __on_completed(self):
|
def __on_completed(self):
|
||||||
logger.info("App starting")
|
logger.info("App starting")
|
||||||
self.reject_close = False
|
|
||||||
self.start_app.emit()
|
self.start_app.emit()
|
||||||
|
|
||||||
def reject(self) -> None:
|
|
||||||
if not self.reject_close:
|
|
||||||
super(LaunchDialog, self).reject()
|
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
from logging import getLogger
|
from logging import getLogger
|
||||||
|
|
||||||
from PyQt5.QtCore import Qt, pyqtSignal
|
from PyQt5.QtCore import Qt
|
||||||
from PyQt5.QtWidgets import QLayout, QDialog, QMessageBox, QFrame
|
from PyQt5.QtWidgets import QLayout, QMessageBox, QFrame
|
||||||
from legendary.core import LegendaryCore
|
from legendary.core import LegendaryCore
|
||||||
|
|
||||||
from rare.shared import ArgumentsSingleton
|
from rare.shared import ArgumentsSingleton
|
||||||
from rare.ui.components.dialogs.login.landing_page import Ui_LandingPage
|
from rare.ui.components.dialogs.login.landing_page import Ui_LandingPage
|
||||||
from rare.ui.components.dialogs.login.login_dialog import Ui_LoginDialog
|
from rare.ui.components.dialogs.login.login_dialog import Ui_LoginDialog
|
||||||
|
from rare.utils.misc import icon
|
||||||
|
from rare.widgets.dialogs import BaseDialog
|
||||||
from rare.widgets.sliding_stack import SlidingStackedWidget
|
from rare.widgets.sliding_stack import SlidingStackedWidget
|
||||||
from .browser_login import BrowserLogin
|
from .browser_login import BrowserLogin
|
||||||
from .import_login import ImportLogin
|
from .import_login import ImportLogin
|
||||||
|
@ -22,12 +24,10 @@ class LandingPage(QFrame):
|
||||||
self.ui.setupUi(self)
|
self.ui.setupUi(self)
|
||||||
|
|
||||||
|
|
||||||
class LoginDialog(QDialog):
|
class LoginDialog(BaseDialog):
|
||||||
exit_app: pyqtSignal = pyqtSignal(int)
|
|
||||||
|
|
||||||
def __init__(self, core: LegendaryCore, parent=None):
|
def __init__(self, core: LegendaryCore, parent=None):
|
||||||
super(LoginDialog, self).__init__(parent=parent)
|
super(LoginDialog, self).__init__(parent=parent)
|
||||||
self.setAttribute(Qt.WA_DeleteOnClose, True)
|
|
||||||
self.setWindowFlags(
|
self.setWindowFlags(
|
||||||
Qt.Window
|
Qt.Window
|
||||||
| Qt.Dialog
|
| Qt.Dialog
|
||||||
|
@ -38,7 +38,7 @@ class LoginDialog(QDialog):
|
||||||
| Qt.WindowCloseButtonHint
|
| Qt.WindowCloseButtonHint
|
||||||
| Qt.MSWindowsFixedSizeDialogHint
|
| Qt.MSWindowsFixedSizeDialogHint
|
||||||
)
|
)
|
||||||
self.setWindowModality(Qt.WindowModal)
|
|
||||||
self.ui = Ui_LoginDialog()
|
self.ui = Ui_LoginDialog()
|
||||||
self.ui.setupUi(self)
|
self.ui.setupUi(self)
|
||||||
|
|
||||||
|
@ -93,13 +93,22 @@ class LoginDialog(QDialog):
|
||||||
self.landing_page.ui.login_import_radio.clicked.connect(lambda: self.ui.next_button.setEnabled(True))
|
self.landing_page.ui.login_import_radio.clicked.connect(lambda: self.ui.next_button.setEnabled(True))
|
||||||
self.landing_page.ui.login_import_radio.clicked.connect(self.import_radio_clicked)
|
self.landing_page.ui.login_import_radio.clicked.connect(self.import_radio_clicked)
|
||||||
|
|
||||||
self.ui.exit_button.clicked.connect(self.close)
|
self.ui.exit_button.clicked.connect(self.reject)
|
||||||
self.ui.back_button.clicked.connect(self.back_clicked)
|
self.ui.back_button.clicked.connect(self.back_clicked)
|
||||||
self.ui.next_button.clicked.connect(self.next_clicked)
|
self.ui.next_button.clicked.connect(self.next_clicked)
|
||||||
|
|
||||||
self.login_stack.setCurrentWidget(self.landing_page)
|
self.login_stack.setCurrentWidget(self.landing_page)
|
||||||
|
|
||||||
self.layout().setSizeConstraint(QLayout.SetFixedSize)
|
self.ui.exit_button.setIcon(icon("fa.remove"))
|
||||||
|
self.ui.back_button.setIcon(icon("fa.chevron-left"))
|
||||||
|
self.ui.next_button.setIcon(icon("fa.chevron-right"))
|
||||||
|
|
||||||
|
# lk: Set next as the default button only to stop closing the dialog when pressing enter
|
||||||
|
self.ui.exit_button.setAutoDefault(False)
|
||||||
|
self.ui.back_button.setAutoDefault(False)
|
||||||
|
self.ui.next_button.setAutoDefault(True)
|
||||||
|
|
||||||
|
self.ui.main_layout.setSizeConstraint(QLayout.SetFixedSize)
|
||||||
|
|
||||||
def back_clicked(self):
|
def back_clicked(self):
|
||||||
self.ui.back_button.setEnabled(False)
|
self.ui.back_button.setEnabled(False)
|
||||||
|
@ -129,15 +138,14 @@ class LoginDialog(QDialog):
|
||||||
|
|
||||||
def login(self):
|
def login(self):
|
||||||
if self.args.test_start:
|
if self.args.test_start:
|
||||||
return False
|
self.reject()
|
||||||
self.exec_()
|
self.open()
|
||||||
return self.logged_in
|
|
||||||
|
|
||||||
def login_successful(self):
|
def login_successful(self):
|
||||||
try:
|
try:
|
||||||
if self.core.login():
|
if self.core.login():
|
||||||
self.logged_in = True
|
self.logged_in = True
|
||||||
self.close()
|
self.accept()
|
||||||
else:
|
else:
|
||||||
raise ValueError("Login failed.")
|
raise ValueError("Login failed.")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@ -146,3 +154,4 @@ class LoginDialog(QDialog):
|
||||||
self.ui.next_button.setEnabled(False)
|
self.ui.next_button.setEnabled(False)
|
||||||
self.logged_in = False
|
self.logged_in = False
|
||||||
QMessageBox.warning(None, self.tr("Login error"), str(e))
|
QMessageBox.warning(None, self.tr("Login error"), str(e))
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ class ListWidget(object):
|
||||||
|
|
||||||
self.install_btn = QPushButton(parent=widget)
|
self.install_btn = QPushButton(parent=widget)
|
||||||
self.install_btn.setObjectName(f"{type(self).__name__}Button")
|
self.install_btn.setObjectName(f"{type(self).__name__}Button")
|
||||||
self.install_btn.setIcon(icon("ri.install-fill"))
|
self.install_btn.setIcon(icon("ri.install-line"))
|
||||||
self.install_btn.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
|
self.install_btn.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
|
||||||
self.install_btn.setFixedWidth(120)
|
self.install_btn.setFixedWidth(120)
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,9 @@ from legendary.lfs import eos
|
||||||
from rare.models.install import InstallOptionsModel
|
from rare.models.install import InstallOptionsModel
|
||||||
from rare.shared import LegendaryCoreSingleton, GlobalSignalsSingleton
|
from rare.shared import LegendaryCoreSingleton, GlobalSignalsSingleton
|
||||||
from rare.ui.components.tabs.games.integrations.eos_widget import Ui_EosWidget
|
from rare.ui.components.tabs.games.integrations.eos_widget import Ui_EosWidget
|
||||||
|
from rare.utils.misc import icon
|
||||||
|
|
||||||
logger = getLogger("EOS")
|
logger = getLogger("EpicOverlay")
|
||||||
|
|
||||||
|
|
||||||
def get_wine_prefixes() -> List[str]:
|
def get_wine_prefixes() -> List[str]:
|
||||||
|
@ -42,83 +43,86 @@ class CheckForUpdateWorker(QRunnable):
|
||||||
self.signals.update_available.emit(self.core.overlay_update_available)
|
self.signals.update_available.emit(self.core.overlay_update_available)
|
||||||
|
|
||||||
|
|
||||||
class EOSGroup(QGroupBox, Ui_EosWidget):
|
class EOSGroup(QGroupBox):
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
super(EOSGroup, self).__init__(parent=parent)
|
super(EOSGroup, self).__init__(parent=parent)
|
||||||
self.setupUi(self)
|
self.ui = Ui_EosWidget()
|
||||||
|
self.ui.setupUi(self)
|
||||||
# lk: set object names for CSS properties
|
# lk: set object names for CSS properties
|
||||||
self.install_button.setObjectName("InstallButton")
|
self.ui.install_button.setObjectName("InstallButton")
|
||||||
self.uninstall_button.setObjectName("UninstallButton")
|
self.ui.install_button.setIcon(icon("ri.install-line"))
|
||||||
|
self.ui.uninstall_button.setObjectName("UninstallButton")
|
||||||
|
self.ui.uninstall_button.setIcon(icon("ri.uninstall-line"))
|
||||||
|
|
||||||
self.core = LegendaryCoreSingleton()
|
self.core = LegendaryCoreSingleton()
|
||||||
self.signals = GlobalSignalsSingleton()
|
self.signals = GlobalSignalsSingleton()
|
||||||
|
|
||||||
self.prefix_enabled = False
|
self.prefix_enabled = False
|
||||||
|
|
||||||
self.enabled_cb.stateChanged.connect(self.change_enable)
|
self.ui.enabled_cb.stateChanged.connect(self.change_enable)
|
||||||
self.uninstall_button.clicked.connect(self.uninstall_overlay)
|
self.ui.uninstall_button.clicked.connect(self.uninstall_overlay)
|
||||||
|
|
||||||
self.update_button.setVisible(False)
|
self.ui.update_button.setVisible(False)
|
||||||
self.overlay = self.core.lgd.get_overlay_install_info()
|
self.overlay = self.core.lgd.get_overlay_install_info()
|
||||||
|
|
||||||
self.signals.application.overlay_installed.connect(self.overlay_installation_finished)
|
self.signals.application.overlay_installed.connect(self.overlay_installation_finished)
|
||||||
self.signals.application.prefix_updated.connect(self.update_prefixes)
|
self.signals.application.prefix_updated.connect(self.update_prefixes)
|
||||||
|
|
||||||
self.update_check_button.clicked.connect(self.check_for_update)
|
self.ui.update_check_button.clicked.connect(self.check_for_update)
|
||||||
self.install_button.clicked.connect(self.install_overlay)
|
self.ui.install_button.clicked.connect(self.install_overlay)
|
||||||
self.update_button.clicked.connect(lambda: self.install_overlay(True))
|
self.ui.update_button.clicked.connect(lambda: self.install_overlay(True))
|
||||||
|
|
||||||
if self.overlay: # installed
|
if self.overlay: # installed
|
||||||
self.installed_version_lbl.setText(f"<b>{self.overlay.version}</b>")
|
self.ui.installed_version_lbl.setText(f"<b>{self.overlay.version}</b>")
|
||||||
self.installed_path_lbl.setText(f"<b>{self.overlay.install_path}</b>")
|
self.ui.installed_path_lbl.setText(f"<b>{self.overlay.install_path}</b>")
|
||||||
self.overlay_stack.setCurrentIndex(0)
|
self.ui.overlay_stack.setCurrentIndex(0)
|
||||||
else:
|
else:
|
||||||
self.overlay_stack.setCurrentIndex(1)
|
self.ui.overlay_stack.setCurrentIndex(1)
|
||||||
self.enable_frame.setDisabled(True)
|
self.ui.enable_frame.setDisabled(True)
|
||||||
|
|
||||||
if platform.system() == "Windows":
|
if platform.system() == "Windows":
|
||||||
self.current_prefix = None
|
self.current_prefix = None
|
||||||
self.select_pfx_combo.setVisible(False)
|
self.ui.select_pfx_combo.setVisible(False)
|
||||||
else:
|
else:
|
||||||
self.current_prefix = os.path.expanduser("~/.wine") \
|
self.current_prefix = os.path.expanduser("~/.wine") \
|
||||||
if os.path.exists(os.path.expanduser("~/.wine")) \
|
if os.path.exists(os.path.expanduser("~/.wine")) \
|
||||||
else None
|
else None
|
||||||
pfxs = get_wine_prefixes()
|
pfxs = get_wine_prefixes()
|
||||||
for pfx in pfxs:
|
for pfx in pfxs:
|
||||||
self.select_pfx_combo.addItem(pfx.replace(os.path.expanduser("~/"), "~/"))
|
self.ui.select_pfx_combo.addItem(pfx.replace(os.path.expanduser("~/"), "~/"))
|
||||||
if not pfxs:
|
if not pfxs:
|
||||||
self.enable_frame.setDisabled(True)
|
self.ui.enable_frame.setDisabled(True)
|
||||||
else:
|
else:
|
||||||
self.select_pfx_combo.setCurrentIndex(0)
|
self.ui.select_pfx_combo.setCurrentIndex(0)
|
||||||
|
|
||||||
self.select_pfx_combo.currentIndexChanged.connect(self.update_select_combo)
|
self.ui.select_pfx_combo.currentIndexChanged.connect(self.update_select_combo)
|
||||||
if pfxs:
|
if pfxs:
|
||||||
self.update_select_combo(None)
|
self.update_select_combo(None)
|
||||||
|
|
||||||
self.enabled_info_label.setText("")
|
self.ui.enabled_info_label.setText("")
|
||||||
|
|
||||||
self.threadpool = QThreadPool.globalInstance()
|
self.threadpool = QThreadPool.globalInstance()
|
||||||
|
|
||||||
def update_prefixes(self):
|
def update_prefixes(self):
|
||||||
logger.debug("Updated prefixes")
|
logger.debug("Updated prefixes")
|
||||||
pfxs = get_wine_prefixes() # returns /home/whatever
|
pfxs = get_wine_prefixes() # returns /home/whatever
|
||||||
self.select_pfx_combo.clear()
|
self.ui.select_pfx_combo.clear()
|
||||||
|
|
||||||
for pfx in pfxs:
|
for pfx in pfxs:
|
||||||
self.select_pfx_combo.addItem(pfx.replace(os.path.expanduser("~/"), "~/"))
|
self.ui.select_pfx_combo.addItem(pfx.replace(os.path.expanduser("~/"), "~/"))
|
||||||
|
|
||||||
if self.current_prefix in pfxs:
|
if self.current_prefix in pfxs:
|
||||||
self.select_pfx_combo.setCurrentIndex(
|
self.ui.select_pfx_combo.setCurrentIndex(
|
||||||
self.select_pfx_combo.findText(self.current_prefix.replace(os.path.expanduser("~/"), "~/")))
|
self.ui.select_pfx_combo.findText(self.current_prefix.replace(os.path.expanduser("~/"), "~/")))
|
||||||
|
|
||||||
def check_for_update(self):
|
def check_for_update(self):
|
||||||
def worker_finished(update_available):
|
def worker_finished(update_available):
|
||||||
self.update_button.setVisible(update_available)
|
self.ui.update_button.setVisible(update_available)
|
||||||
self.update_check_button.setDisabled(False)
|
self.ui.update_check_button.setDisabled(False)
|
||||||
if not update_available:
|
if not update_available:
|
||||||
self.update_check_button.setText(self.tr("No update available"))
|
self.ui.update_check_button.setText(self.tr("No update available"))
|
||||||
|
|
||||||
self.update_check_button.setDisabled(True)
|
self.ui.update_check_button.setDisabled(True)
|
||||||
worker = CheckForUpdateWorker()
|
worker = CheckForUpdateWorker()
|
||||||
worker.signals.update_available.connect(worker_finished)
|
worker.signals.update_available.connect(worker_finished)
|
||||||
QThreadPool.globalInstance().start(worker)
|
QThreadPool.globalInstance().start(worker)
|
||||||
|
@ -131,18 +135,18 @@ class EOSGroup(QGroupBox, Ui_EosWidget):
|
||||||
QMessageBox.warning(self, "Error", self.tr("Something went wrong, when installing overlay"))
|
QMessageBox.warning(self, "Error", self.tr("Something went wrong, when installing overlay"))
|
||||||
return
|
return
|
||||||
|
|
||||||
self.overlay_stack.setCurrentIndex(0)
|
self.ui.overlay_stack.setCurrentIndex(0)
|
||||||
self.installed_version_lbl.setText(f"<b>{self.overlay.version}</b>")
|
self.ui.installed_version_lbl.setText(f"<b>{self.overlay.version}</b>")
|
||||||
self.installed_path_lbl.setText(f"<b>{self.overlay.install_path}</b>")
|
self.ui.installed_path_lbl.setText(f"<b>{self.overlay.install_path}</b>")
|
||||||
|
|
||||||
self.update_button.setVisible(False)
|
self.ui.update_button.setVisible(False)
|
||||||
|
|
||||||
self.enable_frame.setEnabled(True)
|
self.ui.enable_frame.setEnabled(True)
|
||||||
|
|
||||||
def update_select_combo(self, i: None):
|
def update_select_combo(self, i: None):
|
||||||
if i is None:
|
if i is None:
|
||||||
i = self.select_pfx_combo.currentIndex()
|
i = self.ui.select_pfx_combo.currentIndex()
|
||||||
prefix = os.path.expanduser(self.select_pfx_combo.itemText(i))
|
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")):
|
if platform.system() != "Windows" and not os.path.isfile(os.path.join(prefix, "user.reg")):
|
||||||
return
|
return
|
||||||
self.current_prefix = prefix
|
self.current_prefix = prefix
|
||||||
|
@ -151,10 +155,10 @@ class EOSGroup(QGroupBox, Ui_EosWidget):
|
||||||
overlay_enabled = False
|
overlay_enabled = False
|
||||||
if reg_paths['overlay_path'] and self.core.is_overlay_install(reg_paths['overlay_path']):
|
if reg_paths['overlay_path'] and self.core.is_overlay_install(reg_paths['overlay_path']):
|
||||||
overlay_enabled = True
|
overlay_enabled = True
|
||||||
self.enabled_cb.setChecked(overlay_enabled)
|
self.ui.enabled_cb.setChecked(overlay_enabled)
|
||||||
|
|
||||||
def change_enable(self):
|
def change_enable(self):
|
||||||
enabled = self.enabled_cb.isChecked()
|
enabled = self.ui.enabled_cb.isChecked()
|
||||||
if not enabled:
|
if not enabled:
|
||||||
try:
|
try:
|
||||||
eos.remove_registry_entries(self.current_prefix)
|
eos.remove_registry_entries(self.current_prefix)
|
||||||
|
@ -164,7 +168,7 @@ class EOSGroup(QGroupBox, Ui_EosWidget):
|
||||||
"Failed to disable Overlay. Probably it is installed by Epic Games Launcher"))
|
"Failed to disable Overlay. Probably it is installed by Epic Games Launcher"))
|
||||||
return
|
return
|
||||||
logger.info("Disabled Epic Overlay")
|
logger.info("Disabled Epic Overlay")
|
||||||
self.enabled_info_label.setText(self.tr("Disabled"))
|
self.ui.enabled_info_label.setText(self.tr("Disabled"))
|
||||||
else:
|
else:
|
||||||
if not self.overlay:
|
if not self.overlay:
|
||||||
available_installs = self.core.search_overlay_installs(self.current_prefix)
|
available_installs = self.core.search_overlay_installs(self.current_prefix)
|
||||||
|
@ -177,7 +181,7 @@ class EOSGroup(QGroupBox, Ui_EosWidget):
|
||||||
|
|
||||||
if not self.core.is_overlay_install(path):
|
if not self.core.is_overlay_install(path):
|
||||||
logger.error(f'Not a valid Overlay installation: {path}')
|
logger.error(f'Not a valid Overlay installation: {path}')
|
||||||
self.select_pfx_combo.removeItem(self.select_pfx_combo.currentIndex())
|
self.ui.select_pfx_combo.removeItem(self.ui.select_pfx_combo.currentIndex())
|
||||||
return
|
return
|
||||||
|
|
||||||
path = os.path.normpath(path)
|
path = os.path.normpath(path)
|
||||||
|
@ -202,7 +206,7 @@ class EOSGroup(QGroupBox, Ui_EosWidget):
|
||||||
QMessageBox.warning(self, "Error", self.tr(
|
QMessageBox.warning(self, "Error", self.tr(
|
||||||
"Failed to enable EOS overlay. Maybe it is already installed by Epic Games Launcher"))
|
"Failed to enable EOS overlay. Maybe it is already installed by Epic Games Launcher"))
|
||||||
return
|
return
|
||||||
self.enabled_info_label.setText(self.tr("Enabled"))
|
self.ui.enabled_info_label.setText(self.tr("Enabled"))
|
||||||
logger.info(f'Enabled overlay at: {path}')
|
logger.info(f'Enabled overlay at: {path}')
|
||||||
|
|
||||||
def update_checkbox(self):
|
def update_checkbox(self):
|
||||||
|
@ -210,14 +214,14 @@ class EOSGroup(QGroupBox, Ui_EosWidget):
|
||||||
enabled = False
|
enabled = False
|
||||||
if reg_paths['overlay_path'] and self.core.is_overlay_install(reg_paths['overlay_path']):
|
if reg_paths['overlay_path'] and self.core.is_overlay_install(reg_paths['overlay_path']):
|
||||||
enabled = True
|
enabled = True
|
||||||
self.enabled_cb.setChecked(enabled)
|
self.ui.enabled_cb.setChecked(enabled)
|
||||||
|
|
||||||
def install_overlay(self, update=False):
|
def install_overlay(self, update=False):
|
||||||
base_path = os.path.join(self.core.get_default_install_dir(), ".overlay")
|
base_path = os.path.join(self.core.get_default_install_dir(), ".overlay")
|
||||||
if update:
|
if update:
|
||||||
if not self.overlay:
|
if not self.overlay:
|
||||||
self.overlay_stack.setCurrentIndex(1)
|
self.ui.overlay_stack.setCurrentIndex(1)
|
||||||
self.enable_frame.setDisabled(True)
|
self.ui.enable_frame.setDisabled(True)
|
||||||
QMessageBox.warning(self, "Warning", self.tr("Overlay is not installed. Could not update"))
|
QMessageBox.warning(self, "Warning", self.tr("Overlay is not installed. Could not update"))
|
||||||
return
|
return
|
||||||
base_path = self.overlay.install_path
|
base_path = self.overlay.install_path
|
||||||
|
@ -231,7 +235,7 @@ class EOSGroup(QGroupBox, Ui_EosWidget):
|
||||||
def uninstall_overlay(self):
|
def uninstall_overlay(self):
|
||||||
if not self.core.is_overlay_installed():
|
if not self.core.is_overlay_installed():
|
||||||
logger.error('No legendary-managed overlay installation found.')
|
logger.error('No legendary-managed overlay installation found.')
|
||||||
self.overlay_stack.setCurrentIndex(1)
|
self.ui.overlay_stack.setCurrentIndex(1)
|
||||||
return
|
return
|
||||||
|
|
||||||
if QMessageBox.No == QMessageBox.question(
|
if QMessageBox.No == QMessageBox.question(
|
||||||
|
@ -242,7 +246,7 @@ class EOSGroup(QGroupBox, Ui_EosWidget):
|
||||||
if platform.system() == "Windows":
|
if platform.system() == "Windows":
|
||||||
eos.remove_registry_entries(None)
|
eos.remove_registry_entries(None)
|
||||||
else:
|
else:
|
||||||
for prefix in [self.select_pfx_combo.itemText(i) for i in range(self.select_pfx_combo.count())]:
|
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}")
|
logger.info(f"Removing registry entries from {prefix}")
|
||||||
try:
|
try:
|
||||||
eos.remove_registry_entries(os.path.expanduser(prefix))
|
eos.remove_registry_entries(os.path.expanduser(prefix))
|
||||||
|
@ -250,6 +254,6 @@ class EOSGroup(QGroupBox, Ui_EosWidget):
|
||||||
logger.warning(f"{prefix}: {e}")
|
logger.warning(f"{prefix}: {e}")
|
||||||
|
|
||||||
self.core.remove_overlay_install()
|
self.core.remove_overlay_install()
|
||||||
self.overlay_stack.setCurrentIndex(1)
|
self.ui.overlay_stack.setCurrentIndex(1)
|
||||||
|
|
||||||
self.enable_frame.setDisabled(True)
|
self.ui.enable_frame.setDisabled(True)
|
||||||
|
|
|
@ -8,12 +8,15 @@ from PyQt5.QtWidgets import (
|
||||||
)
|
)
|
||||||
|
|
||||||
from rare.components.tabs.settings.widgets.env_vars import EnvVars
|
from rare.components.tabs.settings.widgets.env_vars import EnvVars
|
||||||
from rare.components.tabs.settings.widgets.linux import LinuxSettings
|
|
||||||
from rare.components.tabs.settings.widgets.proton import ProtonSettings
|
|
||||||
from rare.components.tabs.settings.widgets.wrapper import WrapperSettings
|
from rare.components.tabs.settings.widgets.wrapper import WrapperSettings
|
||||||
from rare.shared import LegendaryCoreSingleton
|
from rare.shared import LegendaryCoreSingleton
|
||||||
from rare.ui.components.tabs.settings.game_settings import Ui_GameSettings
|
from rare.ui.components.tabs.settings.game_settings import Ui_GameSettings
|
||||||
|
|
||||||
|
if platform.system() != "Windows":
|
||||||
|
from rare.components.tabs.settings.widgets.linux import LinuxSettings
|
||||||
|
if platform.system() != "Darwin":
|
||||||
|
from rare.components.tabs.settings.widgets.proton import ProtonSettings
|
||||||
|
|
||||||
logger = getLogger("GameSettings")
|
logger = getLogger("GameSettings")
|
||||||
|
|
||||||
|
|
||||||
|
@ -88,15 +91,16 @@ class DefaultGameSettings(QWidget):
|
||||||
self.env_vars.update_game(app_name)
|
self.env_vars.update_game(app_name)
|
||||||
|
|
||||||
|
|
||||||
class LinuxAppSettings(LinuxSettings):
|
if platform.system() != "Windows":
|
||||||
def __init__(self):
|
class LinuxAppSettings(LinuxSettings):
|
||||||
super(LinuxAppSettings, self).__init__()
|
def __init__(self):
|
||||||
|
super(LinuxAppSettings, self).__init__()
|
||||||
|
|
||||||
def update_game(self, app_name):
|
def update_game(self, app_name):
|
||||||
self.name = app_name
|
self.name = app_name
|
||||||
self.wine_prefix.setText(self.load_prefix())
|
self.wine_prefix.setText(self.load_prefix())
|
||||||
self.wine_exec.setText(self.load_setting(self.name, "wine_executable"))
|
self.wine_exec.setText(self.load_setting(self.name, "wine_executable"))
|
||||||
|
|
||||||
self.dxvk.load_settings(self.name)
|
self.dxvk.load_settings(self.name)
|
||||||
|
|
||||||
self.mangohud.load_settings(self.name)
|
self.mangohud.load_settings(self.name)
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import platform
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
from collections import ChainMap
|
from collections import ChainMap
|
||||||
|
@ -9,6 +10,10 @@ from PyQt5.QtGui import QFont
|
||||||
from rare.lgndr.core import LegendaryCore
|
from rare.lgndr.core import LegendaryCore
|
||||||
from rare.utils.misc import icon
|
from rare.utils.misc import icon
|
||||||
|
|
||||||
|
if platform.system() != "Windows":
|
||||||
|
if platform.system() != "Darwin":
|
||||||
|
from rare.utils import proton
|
||||||
|
|
||||||
|
|
||||||
class EnvVarsTableModel(QAbstractTableModel):
|
class EnvVarsTableModel(QAbstractTableModel):
|
||||||
def __init__(self, core: LegendaryCore, parent = None):
|
def __init__(self, core: LegendaryCore, parent = None):
|
||||||
|
@ -23,11 +28,13 @@ class EnvVarsTableModel(QAbstractTableModel):
|
||||||
|
|
||||||
self.__readonly = [
|
self.__readonly = [
|
||||||
"STEAM_COMPAT_DATA_PATH",
|
"STEAM_COMPAT_DATA_PATH",
|
||||||
"STEAM_COMPAT_CLIENT_INSTALL_PATH",
|
|
||||||
"WINEPREFIX",
|
"WINEPREFIX",
|
||||||
"DXVK_HUD",
|
"DXVK_HUD",
|
||||||
"MANGOHUD_CONFIG",
|
"MANGOHUD_CONFIG",
|
||||||
]
|
]
|
||||||
|
if platform.system() != "Windows":
|
||||||
|
if platform.system() != "Darwin":
|
||||||
|
self.__readonly.extend(proton.get_steam_environment(None).keys())
|
||||||
|
|
||||||
self.__default: str = "default"
|
self.__default: str = "default"
|
||||||
self.__appname: str = None
|
self.__appname: str = None
|
||||||
|
|
|
@ -9,37 +9,13 @@ from PyQt5.QtWidgets import QGroupBox, QFileDialog
|
||||||
from rare.components.tabs.settings import LinuxSettings
|
from rare.components.tabs.settings import LinuxSettings
|
||||||
from rare.shared import LegendaryCoreSingleton
|
from rare.shared import LegendaryCoreSingleton
|
||||||
from rare.ui.components.tabs.settings.proton import Ui_ProtonSettings
|
from rare.ui.components.tabs.settings.proton import Ui_ProtonSettings
|
||||||
from rare.utils import config_helper
|
from rare.utils import config_helper, proton
|
||||||
from rare.widgets.indicator_edit import PathEdit, IndicatorReasonsCommon
|
from rare.widgets.indicator_edit import PathEdit, IndicatorReasonsCommon
|
||||||
from .wrapper import WrapperSettings
|
from .wrapper import WrapperSettings
|
||||||
|
|
||||||
logger = getLogger("Proton")
|
logger = getLogger("Proton")
|
||||||
|
|
||||||
|
|
||||||
def find_proton_combos():
|
|
||||||
possible_proton_combos = []
|
|
||||||
compatibilitytools_dirs = [
|
|
||||||
os.path.expanduser("~/.steam/steam/steamapps/common"),
|
|
||||||
"/usr/share/steam/compatibilitytools.d",
|
|
||||||
os.path.expanduser("~/.steam/compatibilitytools.d"),
|
|
||||||
os.path.expanduser("~/.steam/root/compatibilitytools.d"),
|
|
||||||
]
|
|
||||||
for c in compatibilitytools_dirs:
|
|
||||||
if os.path.exists(c):
|
|
||||||
for i in os.listdir(c):
|
|
||||||
proton = os.path.join(c, i, "proton")
|
|
||||||
compatibilitytool = os.path.join(c, i, "compatibilitytool.vdf")
|
|
||||||
toolmanifest = os.path.join(c, i, "toolmanifest.vdf")
|
|
||||||
if os.path.exists(proton) and (
|
|
||||||
os.path.exists(compatibilitytool) or os.path.exists(toolmanifest)
|
|
||||||
):
|
|
||||||
wrapper = f'"{proton}" run'
|
|
||||||
possible_proton_combos.append(wrapper)
|
|
||||||
if not possible_proton_combos:
|
|
||||||
logger.warning("Unable to find any Proton version")
|
|
||||||
return possible_proton_combos
|
|
||||||
|
|
||||||
|
|
||||||
class ProtonSettings(QGroupBox):
|
class ProtonSettings(QGroupBox):
|
||||||
# str: option key
|
# str: option key
|
||||||
environ_changed = pyqtSignal(str)
|
environ_changed = pyqtSignal(str)
|
||||||
|
@ -53,7 +29,7 @@ class ProtonSettings(QGroupBox):
|
||||||
self._linux_settings = linux_settings
|
self._linux_settings = linux_settings
|
||||||
self._wrapper_settings = wrapper_settings
|
self._wrapper_settings = wrapper_settings
|
||||||
self.core = LegendaryCoreSingleton()
|
self.core = LegendaryCoreSingleton()
|
||||||
self.possible_proton_combos = find_proton_combos()
|
self.possible_proton_combos = proton.find_proton_combos()
|
||||||
|
|
||||||
self.ui.proton_combo.addItems(self.possible_proton_combos)
|
self.ui.proton_combo.addItems(self.possible_proton_combos)
|
||||||
self.ui.proton_combo.currentIndexChanged.connect(self.change_proton)
|
self.ui.proton_combo.currentIndexChanged.connect(self.change_proton)
|
||||||
|
|
|
@ -36,7 +36,7 @@ class Ui_LaunchDialog(object):
|
||||||
|
|
||||||
def retranslateUi(self, LaunchDialog):
|
def retranslateUi(self, LaunchDialog):
|
||||||
_translate = QtCore.QCoreApplication.translate
|
_translate = QtCore.QCoreApplication.translate
|
||||||
LaunchDialog.setWindowTitle(_translate("LaunchDialog", "Launching - Rare"))
|
LaunchDialog.setWindowTitle(_translate("LaunchDialog", "Launching"))
|
||||||
self.title_label.setText(_translate("LaunchDialog", "<h2>Launching Rare</h2>"))
|
self.title_label.setText(_translate("LaunchDialog", "<h2>Launching Rare</h2>"))
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Launching - Rare</string>
|
<string>Launching</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="launch_layout">
|
<layout class="QVBoxLayout" name="launch_layout">
|
||||||
<item>
|
<item>
|
||||||
|
|
|
@ -15,38 +15,38 @@ class Ui_LoginDialog(object):
|
||||||
def setupUi(self, LoginDialog):
|
def setupUi(self, LoginDialog):
|
||||||
LoginDialog.setObjectName("LoginDialog")
|
LoginDialog.setObjectName("LoginDialog")
|
||||||
LoginDialog.resize(241, 128)
|
LoginDialog.resize(241, 128)
|
||||||
self.login_layout = QtWidgets.QVBoxLayout(LoginDialog)
|
self.main_layout = QtWidgets.QVBoxLayout(LoginDialog)
|
||||||
self.login_layout.setObjectName("login_layout")
|
self.main_layout.setObjectName("main_layout")
|
||||||
spacerItem = QtWidgets.QSpacerItem(0, 17, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
|
spacerItem = QtWidgets.QSpacerItem(0, 17, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
|
||||||
self.login_layout.addItem(spacerItem)
|
self.main_layout.addItem(spacerItem)
|
||||||
self.welcome_label = QtWidgets.QLabel(LoginDialog)
|
self.welcome_label = QtWidgets.QLabel(LoginDialog)
|
||||||
self.welcome_label.setObjectName("welcome_label")
|
self.welcome_label.setObjectName("welcome_label")
|
||||||
self.login_layout.addWidget(self.welcome_label)
|
self.main_layout.addWidget(self.welcome_label)
|
||||||
spacerItem1 = QtWidgets.QSpacerItem(0, 17, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
|
spacerItem1 = QtWidgets.QSpacerItem(0, 17, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
|
||||||
self.login_layout.addItem(spacerItem1)
|
self.main_layout.addItem(spacerItem1)
|
||||||
self.login_stack_layout = QtWidgets.QVBoxLayout()
|
self.login_stack_layout = QtWidgets.QVBoxLayout()
|
||||||
self.login_stack_layout.setObjectName("login_stack_layout")
|
self.login_stack_layout.setObjectName("login_stack_layout")
|
||||||
self.login_layout.addLayout(self.login_stack_layout)
|
self.main_layout.addLayout(self.login_stack_layout)
|
||||||
self.button_layout = QtWidgets.QHBoxLayout()
|
self.button_layout = QtWidgets.QHBoxLayout()
|
||||||
self.button_layout.setObjectName("button_layout")
|
self.button_layout.setObjectName("button_layout")
|
||||||
spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
|
||||||
self.button_layout.addItem(spacerItem2)
|
|
||||||
self.exit_button = QtWidgets.QPushButton(LoginDialog)
|
self.exit_button = QtWidgets.QPushButton(LoginDialog)
|
||||||
self.exit_button.setObjectName("exit_button")
|
self.exit_button.setObjectName("exit_button")
|
||||||
self.button_layout.addWidget(self.exit_button)
|
self.button_layout.addWidget(self.exit_button)
|
||||||
|
spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
||||||
|
self.button_layout.addItem(spacerItem2)
|
||||||
self.back_button = QtWidgets.QPushButton(LoginDialog)
|
self.back_button = QtWidgets.QPushButton(LoginDialog)
|
||||||
self.back_button.setObjectName("back_button")
|
self.back_button.setObjectName("back_button")
|
||||||
self.button_layout.addWidget(self.back_button)
|
self.button_layout.addWidget(self.back_button)
|
||||||
self.next_button = QtWidgets.QPushButton(LoginDialog)
|
self.next_button = QtWidgets.QPushButton(LoginDialog)
|
||||||
self.next_button.setObjectName("next_button")
|
self.next_button.setObjectName("next_button")
|
||||||
self.button_layout.addWidget(self.next_button)
|
self.button_layout.addWidget(self.next_button)
|
||||||
self.login_layout.addLayout(self.button_layout)
|
self.main_layout.addLayout(self.button_layout)
|
||||||
|
|
||||||
self.retranslateUi(LoginDialog)
|
self.retranslateUi(LoginDialog)
|
||||||
|
|
||||||
def retranslateUi(self, LoginDialog):
|
def retranslateUi(self, LoginDialog):
|
||||||
_translate = QtCore.QCoreApplication.translate
|
_translate = QtCore.QCoreApplication.translate
|
||||||
LoginDialog.setWindowTitle(_translate("LoginDialog", "Login - Rare"))
|
LoginDialog.setWindowTitle(_translate("LoginDialog", "Login"))
|
||||||
self.welcome_label.setText(_translate("LoginDialog", "<h1>Welcome to Rare</h1>"))
|
self.welcome_label.setText(_translate("LoginDialog", "<h1>Welcome to Rare</h1>"))
|
||||||
self.exit_button.setText(_translate("LoginDialog", "Exit"))
|
self.exit_button.setText(_translate("LoginDialog", "Exit"))
|
||||||
self.back_button.setText(_translate("LoginDialog", "Back"))
|
self.back_button.setText(_translate("LoginDialog", "Back"))
|
||||||
|
|
|
@ -11,9 +11,9 @@
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Login - Rare</string>
|
<string>Login</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="login_layout" stretch="0,0,0,0,0">
|
<layout class="QVBoxLayout" name="main_layout" stretch="0,0,0,0,0">
|
||||||
<item>
|
<item>
|
||||||
<spacer name="login_vspacer_top">
|
<spacer name="login_vspacer_top">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
|
@ -58,6 +58,13 @@
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="button_layout">
|
<layout class="QHBoxLayout" name="button_layout">
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="exit_button">
|
||||||
|
<property name="text">
|
||||||
|
<string>Exit</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="button_hspacer">
|
<spacer name="button_hspacer">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
|
@ -71,13 +78,6 @@
|
||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="exit_button">
|
|
||||||
<property name="text">
|
|
||||||
<string>Exit</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="back_button">
|
<widget class="QPushButton" name="back_button">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# Form implementation generated from reading ui file 'rare/ui/components/tabs/games/import_sync/eos_widget.ui'
|
# Form implementation generated from reading ui file 'rare/ui/components/tabs/games/integrations/eos_widget.ui'
|
||||||
#
|
#
|
||||||
# Created by: PyQt5 UI code generator 5.15.7
|
# Created by: PyQt5 UI code generator 5.15.9
|
||||||
#
|
#
|
||||||
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
|
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
|
||||||
# run again. Do not edit this file unless you know what you are doing.
|
# run again. Do not edit this file unless you know what you are doing.
|
||||||
|
@ -30,99 +30,85 @@ class Ui_EosWidget(object):
|
||||||
self.overlay_stack.setObjectName("overlay_stack")
|
self.overlay_stack.setObjectName("overlay_stack")
|
||||||
self.overlay_info_page = QtWidgets.QWidget()
|
self.overlay_info_page = QtWidgets.QWidget()
|
||||||
self.overlay_info_page.setObjectName("overlay_info_page")
|
self.overlay_info_page.setObjectName("overlay_info_page")
|
||||||
self.formLayout_3 = QtWidgets.QFormLayout(self.overlay_info_page)
|
self.overlay_info_layout = QtWidgets.QFormLayout(self.overlay_info_page)
|
||||||
self.formLayout_3.setLabelAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
self.overlay_info_layout.setLabelAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||||
self.formLayout_3.setFormAlignment(QtCore.Qt.AlignBottom|QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft)
|
self.overlay_info_layout.setFormAlignment(QtCore.Qt.AlignBottom|QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft)
|
||||||
self.formLayout_3.setObjectName("formLayout_3")
|
self.overlay_info_layout.setObjectName("overlay_info_layout")
|
||||||
self.installed_version_info_lbl = QtWidgets.QLabel(self.overlay_info_page)
|
self.installed_version_info_lbl = QtWidgets.QLabel(self.overlay_info_page)
|
||||||
self.installed_version_info_lbl.setObjectName("installed_version_info_lbl")
|
self.installed_version_info_lbl.setObjectName("installed_version_info_lbl")
|
||||||
self.formLayout_3.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.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 = QtWidgets.QLabel(self.overlay_info_page)
|
||||||
self.installed_version_lbl.setText("error")
|
self.installed_version_lbl.setText("error")
|
||||||
self.installed_version_lbl.setObjectName("installed_version_lbl")
|
self.installed_version_lbl.setObjectName("installed_version_lbl")
|
||||||
self.formLayout_3.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.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 = QtWidgets.QLabel(self.overlay_info_page)
|
||||||
self.installed_path_info_lbl.setObjectName("installed_path_info_lbl")
|
self.installed_path_info_lbl.setObjectName("installed_path_info_lbl")
|
||||||
self.formLayout_3.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.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 = QtWidgets.QLabel(self.overlay_info_page)
|
||||||
self.installed_path_lbl.setText("error")
|
self.installed_path_lbl.setText("error")
|
||||||
self.installed_path_lbl.setObjectName("installed_path_lbl")
|
self.installed_path_lbl.setObjectName("installed_path_lbl")
|
||||||
self.formLayout_3.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.installed_path_lbl)
|
self.overlay_info_layout.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.installed_path_lbl)
|
||||||
self.horizontalLayout = QtWidgets.QHBoxLayout()
|
self.info_buttons_layout = QtWidgets.QHBoxLayout()
|
||||||
self.horizontalLayout.setObjectName("horizontalLayout")
|
self.info_buttons_layout.setObjectName("info_buttons_layout")
|
||||||
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
||||||
self.horizontalLayout.addItem(spacerItem)
|
self.info_buttons_layout.addItem(spacerItem)
|
||||||
self.uninstall_button = QtWidgets.QPushButton(self.overlay_info_page)
|
self.uninstall_button = QtWidgets.QPushButton(self.overlay_info_page)
|
||||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Minimum)
|
self.uninstall_button.setMinimumSize(QtCore.QSize(120, 0))
|
||||||
sizePolicy.setHorizontalStretch(0)
|
|
||||||
sizePolicy.setVerticalStretch(0)
|
|
||||||
sizePolicy.setHeightForWidth(self.uninstall_button.sizePolicy().hasHeightForWidth())
|
|
||||||
self.uninstall_button.setSizePolicy(sizePolicy)
|
|
||||||
self.uninstall_button.setMaximumSize(QtCore.QSize(150, 16777215))
|
|
||||||
self.uninstall_button.setObjectName("uninstall_button")
|
self.uninstall_button.setObjectName("uninstall_button")
|
||||||
self.horizontalLayout.addWidget(self.uninstall_button)
|
self.info_buttons_layout.addWidget(self.uninstall_button)
|
||||||
self.update_check_button = QtWidgets.QPushButton(self.overlay_info_page)
|
self.update_check_button = QtWidgets.QPushButton(self.overlay_info_page)
|
||||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Minimum)
|
self.update_check_button.setMinimumSize(QtCore.QSize(120, 0))
|
||||||
sizePolicy.setHorizontalStretch(0)
|
|
||||||
sizePolicy.setVerticalStretch(0)
|
|
||||||
sizePolicy.setHeightForWidth(self.update_check_button.sizePolicy().hasHeightForWidth())
|
|
||||||
self.update_check_button.setSizePolicy(sizePolicy)
|
|
||||||
self.update_check_button.setMaximumSize(QtCore.QSize(150, 16777215))
|
|
||||||
self.update_check_button.setObjectName("update_check_button")
|
self.update_check_button.setObjectName("update_check_button")
|
||||||
self.horizontalLayout.addWidget(self.update_check_button)
|
self.info_buttons_layout.addWidget(self.update_check_button)
|
||||||
self.update_button = QtWidgets.QPushButton(self.overlay_info_page)
|
self.update_button = QtWidgets.QPushButton(self.overlay_info_page)
|
||||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Minimum)
|
self.update_button.setMinimumSize(QtCore.QSize(120, 0))
|
||||||
sizePolicy.setHorizontalStretch(0)
|
|
||||||
sizePolicy.setVerticalStretch(0)
|
|
||||||
sizePolicy.setHeightForWidth(self.update_button.sizePolicy().hasHeightForWidth())
|
|
||||||
self.update_button.setSizePolicy(sizePolicy)
|
|
||||||
self.update_button.setMaximumSize(QtCore.QSize(150, 16777215))
|
|
||||||
self.update_button.setObjectName("update_button")
|
self.update_button.setObjectName("update_button")
|
||||||
self.horizontalLayout.addWidget(self.update_button)
|
self.info_buttons_layout.addWidget(self.update_button)
|
||||||
self.formLayout_3.setLayout(3, QtWidgets.QFormLayout.SpanningRole, self.horizontalLayout)
|
self.overlay_info_layout.setLayout(3, QtWidgets.QFormLayout.SpanningRole, self.info_buttons_layout)
|
||||||
spacerItem1 = QtWidgets.QSpacerItem(6, 6, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
|
spacerItem1 = QtWidgets.QSpacerItem(6, 6, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
|
||||||
self.formLayout_3.setItem(2, QtWidgets.QFormLayout.SpanningRole, spacerItem1)
|
self.overlay_info_layout.setItem(2, QtWidgets.QFormLayout.SpanningRole, spacerItem1)
|
||||||
self.overlay_stack.addWidget(self.overlay_info_page)
|
self.overlay_stack.addWidget(self.overlay_info_page)
|
||||||
self.overlay_install_page = QtWidgets.QWidget()
|
self.overlay_install_page = QtWidgets.QWidget()
|
||||||
self.overlay_install_page.setObjectName("overlay_install_page")
|
self.overlay_install_page.setObjectName("overlay_install_page")
|
||||||
self.formLayout = QtWidgets.QFormLayout(self.overlay_install_page)
|
self.overlay_install_layout = QtWidgets.QFormLayout(self.overlay_install_page)
|
||||||
self.formLayout.setLabelAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
self.overlay_install_layout.setLabelAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||||
self.formLayout.setFormAlignment(QtCore.Qt.AlignBottom|QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft)
|
self.overlay_install_layout.setFormAlignment(QtCore.Qt.AlignBottom|QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft)
|
||||||
self.formLayout.setObjectName("formLayout")
|
self.overlay_install_layout.setObjectName("overlay_install_layout")
|
||||||
self.label = QtWidgets.QLabel(self.overlay_install_page)
|
self.label = QtWidgets.QLabel(self.overlay_install_page)
|
||||||
self.label.setObjectName("label")
|
self.label.setObjectName("label")
|
||||||
self.formLayout.setWidget(0, QtWidgets.QFormLayout.SpanningRole, self.label)
|
self.overlay_install_layout.setWidget(0, QtWidgets.QFormLayout.SpanningRole, self.label)
|
||||||
self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
|
self.install_buttons_layout = QtWidgets.QHBoxLayout()
|
||||||
self.horizontalLayout_3.setObjectName("horizontalLayout_3")
|
self.install_buttons_layout.setObjectName("install_buttons_layout")
|
||||||
spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
||||||
self.horizontalLayout_3.addItem(spacerItem2)
|
self.install_buttons_layout.addItem(spacerItem2)
|
||||||
self.install_button = QtWidgets.QPushButton(self.overlay_install_page)
|
self.install_button = QtWidgets.QPushButton(self.overlay_install_page)
|
||||||
|
self.install_button.setMinimumSize(QtCore.QSize(120, 0))
|
||||||
self.install_button.setObjectName("install_button")
|
self.install_button.setObjectName("install_button")
|
||||||
self.horizontalLayout_3.addWidget(self.install_button)
|
self.install_buttons_layout.addWidget(self.install_button)
|
||||||
self.formLayout.setLayout(2, QtWidgets.QFormLayout.SpanningRole, self.horizontalLayout_3)
|
self.overlay_install_layout.setLayout(2, QtWidgets.QFormLayout.SpanningRole, self.install_buttons_layout)
|
||||||
spacerItem3 = QtWidgets.QSpacerItem(6, 6, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
|
spacerItem3 = QtWidgets.QSpacerItem(6, 6, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
|
||||||
self.formLayout.setItem(1, QtWidgets.QFormLayout.SpanningRole, spacerItem3)
|
self.overlay_install_layout.setItem(1, QtWidgets.QFormLayout.SpanningRole, spacerItem3)
|
||||||
self.overlay_stack.addWidget(self.overlay_install_page)
|
self.overlay_stack.addWidget(self.overlay_install_page)
|
||||||
self.eos_layout.addWidget(self.overlay_stack)
|
self.eos_layout.addWidget(self.overlay_stack)
|
||||||
self.enable_frame = QtWidgets.QFrame(EosWidget)
|
self.enable_frame = QtWidgets.QFrame(EosWidget)
|
||||||
self.enable_frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
|
self.enable_frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
|
||||||
self.enable_frame.setFrameShadow(QtWidgets.QFrame.Raised)
|
self.enable_frame.setFrameShadow(QtWidgets.QFrame.Raised)
|
||||||
self.enable_frame.setObjectName("enable_frame")
|
self.enable_frame.setObjectName("enable_frame")
|
||||||
self.verticalLayout = QtWidgets.QVBoxLayout(self.enable_frame)
|
self.enable_layout = QtWidgets.QVBoxLayout(self.enable_frame)
|
||||||
self.verticalLayout.setObjectName("verticalLayout")
|
self.enable_layout.setObjectName("enable_layout")
|
||||||
self.select_pfx_combo = QtWidgets.QComboBox(self.enable_frame)
|
self.select_pfx_combo = QtWidgets.QComboBox(self.enable_frame)
|
||||||
self.select_pfx_combo.setObjectName("select_pfx_combo")
|
self.select_pfx_combo.setObjectName("select_pfx_combo")
|
||||||
self.verticalLayout.addWidget(self.select_pfx_combo)
|
self.enable_layout.addWidget(self.select_pfx_combo)
|
||||||
self.enabled_cb = QtWidgets.QCheckBox(self.enable_frame)
|
self.enabled_cb = QtWidgets.QCheckBox(self.enable_frame)
|
||||||
self.enabled_cb.setObjectName("enabled_cb")
|
self.enabled_cb.setObjectName("enabled_cb")
|
||||||
self.verticalLayout.addWidget(self.enabled_cb)
|
self.enable_layout.addWidget(self.enabled_cb)
|
||||||
self.enabled_info_label = QtWidgets.QLabel(self.enable_frame)
|
self.enabled_info_label = QtWidgets.QLabel(self.enable_frame)
|
||||||
font = QtGui.QFont()
|
font = QtGui.QFont()
|
||||||
font.setItalic(True)
|
font.setItalic(True)
|
||||||
self.enabled_info_label.setFont(font)
|
self.enabled_info_label.setFont(font)
|
||||||
self.enabled_info_label.setText("")
|
self.enabled_info_label.setText("")
|
||||||
self.enabled_info_label.setObjectName("enabled_info_label")
|
self.enabled_info_label.setObjectName("enabled_info_label")
|
||||||
self.verticalLayout.addWidget(self.enabled_info_label)
|
self.enable_layout.addWidget(self.enabled_info_label)
|
||||||
self.eos_layout.addWidget(self.enable_frame)
|
self.eos_layout.addWidget(self.enable_frame)
|
||||||
|
|
||||||
self.retranslateUi(EosWidget)
|
self.retranslateUi(EosWidget)
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="overlay_info_page">
|
<widget class="QWidget" name="overlay_info_page">
|
||||||
<layout class="QFormLayout" name="formLayout_3">
|
<layout class="QFormLayout" name="overlay_info_layout">
|
||||||
<property name="labelAlignment">
|
<property name="labelAlignment">
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
</property>
|
</property>
|
||||||
|
@ -74,9 +74,9 @@
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="0" colspan="2">
|
<item row="3" column="0" colspan="2">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
<layout class="QHBoxLayout" name="info_buttons_layout">
|
||||||
<item>
|
<item>
|
||||||
<spacer name="horizontalSpacer">
|
<spacer name="info_buttons_hspacer">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
|
@ -90,16 +90,10 @@
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="uninstall_button">
|
<widget class="QPushButton" name="uninstall_button">
|
||||||
<property name="sizePolicy">
|
<property name="minimumSize">
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
<size>
|
||||||
<width>150</width>
|
<width>120</width>
|
||||||
<height>16777215</height>
|
<height>0</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
|
@ -109,16 +103,10 @@
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="update_check_button">
|
<widget class="QPushButton" name="update_check_button">
|
||||||
<property name="sizePolicy">
|
<property name="minimumSize">
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
<size>
|
||||||
<width>150</width>
|
<width>120</width>
|
||||||
<height>16777215</height>
|
<height>0</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
|
@ -128,16 +116,10 @@
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="update_button">
|
<widget class="QPushButton" name="update_button">
|
||||||
<property name="sizePolicy">
|
<property name="minimumSize">
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="maximumSize">
|
|
||||||
<size>
|
<size>
|
||||||
<width>150</width>
|
<width>120</width>
|
||||||
<height>16777215</height>
|
<height>0</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
|
@ -148,7 +130,7 @@
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0" colspan="2">
|
<item row="2" column="0" colspan="2">
|
||||||
<spacer name="verticalSpacer">
|
<spacer name="info_page_vspacer">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Vertical</enum>
|
<enum>Qt::Vertical</enum>
|
||||||
</property>
|
</property>
|
||||||
|
@ -163,7 +145,7 @@
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QWidget" name="overlay_install_page">
|
<widget class="QWidget" name="overlay_install_page">
|
||||||
<layout class="QFormLayout" name="formLayout">
|
<layout class="QFormLayout" name="overlay_install_layout">
|
||||||
<property name="labelAlignment">
|
<property name="labelAlignment">
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
</property>
|
</property>
|
||||||
|
@ -178,9 +160,9 @@
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0" colspan="2">
|
<item row="2" column="0" colspan="2">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
<layout class="QHBoxLayout" name="install_buttons_layout">
|
||||||
<item>
|
<item>
|
||||||
<spacer name="horizontalSpacer_2">
|
<spacer name="install_buttons_hspacer">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
</property>
|
</property>
|
||||||
|
@ -194,6 +176,12 @@
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="install_button">
|
<widget class="QPushButton" name="install_button">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>120</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Install</string>
|
<string>Install</string>
|
||||||
</property>
|
</property>
|
||||||
|
@ -202,7 +190,7 @@
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0" colspan="2">
|
<item row="1" column="0" colspan="2">
|
||||||
<spacer name="verticalSpacer_2">
|
<spacer name="install_page_vspacer">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Vertical</enum>
|
<enum>Qt::Vertical</enum>
|
||||||
</property>
|
</property>
|
||||||
|
@ -226,7 +214,7 @@
|
||||||
<property name="frameShadow">
|
<property name="frameShadow">
|
||||||
<enum>QFrame::Raised</enum>
|
<enum>QFrame::Raised</enum>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="enable_layout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QComboBox" name="select_pfx_combo"/>
|
<widget class="QComboBox" name="select_pfx_combo"/>
|
||||||
</item>
|
</item>
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
from typing import Callable, Optional
|
import os
|
||||||
|
from typing import Callable, Optional, Set, Any
|
||||||
|
|
||||||
from legendary.core import LegendaryCore
|
from legendary.core import LegendaryCore
|
||||||
from legendary.models.config import LGDConf
|
from legendary.models.config import LGDConf
|
||||||
|
@ -40,6 +41,48 @@ def remove_option(app_name, option):
|
||||||
|
|
||||||
def remove_section(app_name):
|
def remove_section(app_name):
|
||||||
return
|
return
|
||||||
|
# Disabled due to env variables implementation
|
||||||
if _config.has_section(app_name):
|
if _config.has_section(app_name):
|
||||||
_config.remove_section(app_name)
|
_config.remove_section(app_name)
|
||||||
save_config()
|
save_config()
|
||||||
|
|
||||||
|
|
||||||
|
def get_game_option(option: str, app_name: Optional[str] = None, fallback: Any = None) -> str:
|
||||||
|
_option = _config.get("default", option, fallback=fallback)
|
||||||
|
if app_name is not None:
|
||||||
|
_option = _config.get(app_name, option, fallback=_option)
|
||||||
|
return _option
|
||||||
|
|
||||||
|
|
||||||
|
def get_game_envvar(option: str, app_name: Optional[str] = None, fallback: Any = None) -> str:
|
||||||
|
_option = _config.get("default.env", option, fallback=fallback)
|
||||||
|
if app_name is not None:
|
||||||
|
_option = _config.get(f'{app_name}.env', option, fallback=_option)
|
||||||
|
return _option
|
||||||
|
|
||||||
|
|
||||||
|
def get_wine_prefix(app_name: Optional[str] = None, fallback: Any = None) -> str:
|
||||||
|
_prefix = os.path.join(
|
||||||
|
_config.get("default.env", "STEAM_COMPAT_DATA_PATH", fallback=fallback), "pfx")
|
||||||
|
if app_name is not None:
|
||||||
|
_prefix = os.path.join(
|
||||||
|
_config.get(f'{app_name}.env', "STEAM_COMPAT_DATA_PATH", fallback=_prefix), "pfx")
|
||||||
|
_prefix = _config.get("default.env", "WINEPREFIX", fallback=_prefix)
|
||||||
|
_prefix = _config.get("default", "wine_prefix", fallback=_prefix)
|
||||||
|
if app_name is not None:
|
||||||
|
_prefix = _config.get(f'{app_name}.env', 'WINEPREFIX', fallback=_prefix)
|
||||||
|
_prefix = _config.get(app_name, 'wine_prefix', fallback=_prefix)
|
||||||
|
return _prefix
|
||||||
|
|
||||||
|
|
||||||
|
def get_wine_prefixes() -> Set[str]:
|
||||||
|
_prefixes = []
|
||||||
|
for name, section in _config.items():
|
||||||
|
pfx = section.get("WINEPREFIX") or section.get("wine_prefix")
|
||||||
|
if not pfx:
|
||||||
|
pfx = os.path.join(compatdata, "pfx") if (compatdata := section.get("STEAM_COMPAT_DATA_PATH")) else ""
|
||||||
|
if pfx:
|
||||||
|
_prefixes.append(pfx)
|
||||||
|
_prefixes = [os.path.expanduser(prefix) for prefix in _prefixes]
|
||||||
|
return {p for p in _prefixes if os.path.isdir(p)}
|
||||||
|
|
||||||
|
|
271
rare/utils/proton.py
Normal file
271
rare/utils/proton.py
Normal file
|
@ -0,0 +1,271 @@
|
||||||
|
import os
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from logging import getLogger
|
||||||
|
from typing import Optional, Union, List, Dict
|
||||||
|
|
||||||
|
import vdf
|
||||||
|
|
||||||
|
logger = getLogger("Proton")
|
||||||
|
|
||||||
|
steam_compat_client_install_paths = [os.path.expanduser("~/.local/share/Steam")]
|
||||||
|
|
||||||
|
|
||||||
|
def find_steam() -> str:
|
||||||
|
# return the first valid path
|
||||||
|
for path in steam_compat_client_install_paths:
|
||||||
|
if os.path.isdir(path) and os.path.isfile(os.path.join(path, "steam.sh")):
|
||||||
|
return path
|
||||||
|
|
||||||
|
|
||||||
|
def find_libraries(steam_path: str) -> List[str]:
|
||||||
|
vdf_path = os.path.join(steam_path, "steamapps", "libraryfolders.vdf")
|
||||||
|
with open(vdf_path, "r") as f:
|
||||||
|
libraryfolders = vdf.load(f)["libraryfolders"]
|
||||||
|
libraries = [os.path.join(folder["path"], "steamapps") for key, folder in libraryfolders.items()]
|
||||||
|
return libraries
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class SteamBase:
|
||||||
|
steam_path: str
|
||||||
|
tool_path: str
|
||||||
|
toolmanifest: dict
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
return self.tool_path == other.tool_path
|
||||||
|
|
||||||
|
def __hash__(self):
|
||||||
|
return hash(self.tool_path)
|
||||||
|
|
||||||
|
def commandline(self):
|
||||||
|
cmd = "".join([f"'{self.tool_path}'", self.toolmanifest["manifest"]["commandline"]])
|
||||||
|
cmd = os.path.normpath(cmd)
|
||||||
|
# NOTE: "waitforexitandrun" seems to be the verb used in by steam to execute stuff
|
||||||
|
cmd = cmd.replace("%verb%", "waitforexitandrun")
|
||||||
|
return cmd
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class SteamRuntime(SteamBase):
|
||||||
|
steam_library: str
|
||||||
|
appmanifest: dict
|
||||||
|
|
||||||
|
def name(self):
|
||||||
|
return self.appmanifest["AppState"]["name"]
|
||||||
|
|
||||||
|
def appid(self):
|
||||||
|
return self.appmanifest["AppState"]["appid"]
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ProtonTool(SteamRuntime):
|
||||||
|
runtime: SteamRuntime = None
|
||||||
|
|
||||||
|
def __bool__(self):
|
||||||
|
if appid := self.toolmanifest.get("require_tool_appid", False):
|
||||||
|
return self.runtime is not None and self.runtime.appid() == appid
|
||||||
|
|
||||||
|
def commandline(self):
|
||||||
|
runtime_cmd = self.runtime.commandline()
|
||||||
|
cmd = super().commandline()
|
||||||
|
return " ".join([runtime_cmd, cmd])
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class CompatibilityTool(SteamBase):
|
||||||
|
compatibilitytool: dict
|
||||||
|
runtime: SteamRuntime = None
|
||||||
|
|
||||||
|
def __bool__(self):
|
||||||
|
if appid := self.toolmanifest.get("require_tool_appid", False):
|
||||||
|
return self.runtime is not None and self.runtime.appid() == appid
|
||||||
|
|
||||||
|
def name(self):
|
||||||
|
name, data = list(self.compatibilitytool["compatibilitytools"]["compat_tools"].items())[0]
|
||||||
|
return data["display_name"]
|
||||||
|
|
||||||
|
def commandline(self):
|
||||||
|
runtime_cmd = self.runtime.commandline() if self.runtime is not None else ""
|
||||||
|
cmd = super().commandline()
|
||||||
|
return " ".join([runtime_cmd, cmd])
|
||||||
|
|
||||||
|
|
||||||
|
def find_appmanifests(library: str) -> List[dict]:
|
||||||
|
appmanifests = []
|
||||||
|
for entry in os.scandir(library):
|
||||||
|
if entry.is_file() and entry.name.endswith(".acf"):
|
||||||
|
with open(os.path.join(library, entry.name), "r") as f:
|
||||||
|
appmanifest = vdf.load(f)
|
||||||
|
appmanifests.append(appmanifest)
|
||||||
|
return appmanifests
|
||||||
|
|
||||||
|
|
||||||
|
def find_protons(steam_path: str, library: str) -> List[ProtonTool]:
|
||||||
|
protons = []
|
||||||
|
appmanifests = find_appmanifests(library)
|
||||||
|
common = os.path.join(library, "common")
|
||||||
|
for appmanifest in appmanifests:
|
||||||
|
folder = appmanifest["AppState"]["installdir"]
|
||||||
|
tool_path = os.path.join(common, folder)
|
||||||
|
if os.path.isfile(vdf_file := os.path.join(tool_path, "toolmanifest.vdf")):
|
||||||
|
with open(vdf_file, "r") as f:
|
||||||
|
toolmanifest = vdf.load(f)
|
||||||
|
if toolmanifest["manifest"]["compatmanager_layer_name"] == "proton":
|
||||||
|
protons.append(
|
||||||
|
ProtonTool(
|
||||||
|
steam_path=steam_path,
|
||||||
|
steam_library=library,
|
||||||
|
appmanifest=appmanifest,
|
||||||
|
tool_path=tool_path,
|
||||||
|
toolmanifest=toolmanifest,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return protons
|
||||||
|
|
||||||
|
|
||||||
|
def find_compatibility_tools(steam_path: str) -> List[CompatibilityTool]:
|
||||||
|
compatibilitytools_paths = {
|
||||||
|
"/usr/share/steam/compatibilitytools.d",
|
||||||
|
os.path.expanduser(os.path.join(steam_path, "compatibilitytools.d")),
|
||||||
|
os.path.expanduser("~/.steam/compatibilitytools.d"),
|
||||||
|
os.path.expanduser("~/.steam/root/compatibilitytools.d"),
|
||||||
|
}
|
||||||
|
compatibilitytools_paths = {
|
||||||
|
os.path.realpath(path) for path in compatibilitytools_paths if os.path.isdir(path)
|
||||||
|
}
|
||||||
|
tools = []
|
||||||
|
for path in compatibilitytools_paths:
|
||||||
|
for entry in os.scandir(path):
|
||||||
|
if entry.is_dir():
|
||||||
|
tool_path = os.path.join(path, entry.name)
|
||||||
|
tool_vdf = os.path.join(tool_path, "compatibilitytool.vdf")
|
||||||
|
manifest_vdf = os.path.join(tool_path, "toolmanifest.vdf")
|
||||||
|
if os.path.isfile(tool_vdf) and os.path.isfile(manifest_vdf):
|
||||||
|
with open(tool_vdf, "r") as f:
|
||||||
|
compatibilitytool = vdf.load(f)
|
||||||
|
with open(manifest_vdf, "r") as f:
|
||||||
|
manifest = vdf.load(f)
|
||||||
|
tools.append(
|
||||||
|
CompatibilityTool(
|
||||||
|
steam_path=steam_path,
|
||||||
|
tool_path=tool_path,
|
||||||
|
toolmanifest=manifest,
|
||||||
|
compatibilitytool=compatibilitytool,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return tools
|
||||||
|
|
||||||
|
|
||||||
|
def find_runtimes(steam_path: str, library: str) -> Dict[str, SteamRuntime]:
|
||||||
|
runtimes = {}
|
||||||
|
appmanifests = find_appmanifests(library)
|
||||||
|
common = os.path.join(library, "common")
|
||||||
|
for appmanifest in appmanifests:
|
||||||
|
folder = appmanifest["AppState"]["installdir"]
|
||||||
|
tool_path = os.path.join(common, folder)
|
||||||
|
if os.path.isfile(vdf_file := os.path.join(tool_path, "toolmanifest.vdf")):
|
||||||
|
with open(vdf_file, "r") as f:
|
||||||
|
toolmanifest = vdf.load(f)
|
||||||
|
if toolmanifest["manifest"]["compatmanager_layer_name"] == "container-runtime":
|
||||||
|
runtimes.update(
|
||||||
|
{
|
||||||
|
appmanifest["AppState"]["appid"]: SteamRuntime(
|
||||||
|
steam_path=steam_path,
|
||||||
|
steam_library=library,
|
||||||
|
appmanifest=appmanifest,
|
||||||
|
tool_path=tool_path,
|
||||||
|
toolmanifest=toolmanifest,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return runtimes
|
||||||
|
|
||||||
|
|
||||||
|
def find_runtime(
|
||||||
|
tool: Union[ProtonTool, CompatibilityTool], runtimes: Dict[str, SteamRuntime]
|
||||||
|
) -> Optional[SteamRuntime]:
|
||||||
|
required_tool = tool.toolmanifest["manifest"].get("require_tool_appid")
|
||||||
|
if required_tool is None:
|
||||||
|
return None
|
||||||
|
return runtimes[required_tool]
|
||||||
|
|
||||||
|
|
||||||
|
def get_steam_environment(tool: Optional[Union[ProtonTool, CompatibilityTool]], app_name: str = None) -> Dict:
|
||||||
|
environ = {}
|
||||||
|
# If the tool is unset, return all affected env variable names
|
||||||
|
# IMPORTANT: keep this in sync with the code below
|
||||||
|
if tool is None:
|
||||||
|
environ["STEAM_COMPAT_CLIENT_INSTALL_PATH"] = ""
|
||||||
|
environ["STEAM_COMPAT_LIBRARY_PATHS"] = ""
|
||||||
|
environ["STEAM_COMPAT_MOUNTS"] = ""
|
||||||
|
environ["STEAM_COMPAT_TOOL_PATHS"] = ""
|
||||||
|
return environ
|
||||||
|
|
||||||
|
environ["STEAM_COMPAT_CLIENT_INSTALL_PATH"] = tool.steam_path
|
||||||
|
if isinstance(tool, ProtonTool):
|
||||||
|
environ["STEAM_COMPAT_LIBRARY_PATHS"] = tool.steam_library
|
||||||
|
if tool.runtime is not None:
|
||||||
|
compat_mounts = [tool.tool_path, tool.runtime.tool_path]
|
||||||
|
environ["STEAM_COMPAT_MOUNTS"] = ":".join(compat_mounts)
|
||||||
|
tool_paths = [tool.tool_path]
|
||||||
|
if tool.runtime is not None:
|
||||||
|
tool_paths.append(tool.runtime.tool_path)
|
||||||
|
environ["STEAM_COMPAT_TOOL_PATHS"] = ":".join(tool_paths)
|
||||||
|
return environ
|
||||||
|
|
||||||
|
|
||||||
|
def find_tools() -> List[Union[ProtonTool, CompatibilityTool]]:
|
||||||
|
steam_path = find_steam()
|
||||||
|
logger.debug("Using Steam install in %s", steam_path)
|
||||||
|
steam_libraries = find_libraries(steam_path)
|
||||||
|
logger.debug("Searching for tools in libraries %s", steam_libraries)
|
||||||
|
|
||||||
|
runtimes = {}
|
||||||
|
for library in steam_libraries:
|
||||||
|
runtimes.update(find_runtimes(steam_path, library))
|
||||||
|
|
||||||
|
tools = []
|
||||||
|
for library in steam_libraries:
|
||||||
|
tools.extend(find_protons(steam_path, library))
|
||||||
|
tools.extend(find_compatibility_tools(steam_path))
|
||||||
|
|
||||||
|
for tool in tools:
|
||||||
|
runtime = find_runtime(tool, runtimes)
|
||||||
|
tool.runtime = runtime
|
||||||
|
|
||||||
|
return tools
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
from pprint import pprint
|
||||||
|
|
||||||
|
_tools = find_tools()
|
||||||
|
pprint(_tools)
|
||||||
|
|
||||||
|
for tool in _tools:
|
||||||
|
print(get_steam_environment(tool))
|
||||||
|
print(tool.name(), tool.commandline())
|
||||||
|
|
||||||
|
|
||||||
|
def find_proton_combos():
|
||||||
|
possible_proton_combos = []
|
||||||
|
compatibilitytools_dirs = [
|
||||||
|
os.path.expanduser("~/.steam/steam/steamapps/common"),
|
||||||
|
"/usr/share/steam/compatibilitytools.d",
|
||||||
|
os.path.expanduser("~/.steam/compatibilitytools.d"),
|
||||||
|
os.path.expanduser("~/.steam/root/compatibilitytools.d"),
|
||||||
|
]
|
||||||
|
for c in compatibilitytools_dirs:
|
||||||
|
if os.path.exists(c):
|
||||||
|
for i in os.listdir(c):
|
||||||
|
proton = os.path.join(c, i, "proton")
|
||||||
|
compatibilitytool = os.path.join(c, i, "compatibilitytool.vdf")
|
||||||
|
toolmanifest = os.path.join(c, i, "toolmanifest.vdf")
|
||||||
|
if os.path.exists(proton) and (
|
||||||
|
os.path.exists(compatibilitytool) or os.path.exists(toolmanifest)
|
||||||
|
):
|
||||||
|
wrapper = f'"{proton}" run'
|
||||||
|
possible_proton_combos.append(wrapper)
|
||||||
|
if not possible_proton_combos:
|
||||||
|
logger.warning("Unable to find any Proton version")
|
||||||
|
return possible_proton_combos
|
283
rare/widgets/dialogs.py
Normal file
283
rare/widgets/dialogs.py
Normal file
|
@ -0,0 +1,283 @@
|
||||||
|
import sys
|
||||||
|
from abc import abstractmethod
|
||||||
|
|
||||||
|
from PyQt5.QtCore import Qt, pyqtSlot, QCoreApplication, QSize
|
||||||
|
from PyQt5.QtGui import QCloseEvent, QKeyEvent, QKeySequence
|
||||||
|
from PyQt5.QtWidgets import (
|
||||||
|
QDialog,
|
||||||
|
QDialogButtonBox,
|
||||||
|
QApplication,
|
||||||
|
QPushButton,
|
||||||
|
QVBoxLayout,
|
||||||
|
QHBoxLayout,
|
||||||
|
QWidget,
|
||||||
|
QLayout, QSpacerItem, QSizePolicy,
|
||||||
|
)
|
||||||
|
|
||||||
|
from rare.utils.misc import icon
|
||||||
|
|
||||||
|
|
||||||
|
def dialog_title_game(text: str, app_title: str) -> str:
|
||||||
|
return f"{text} '{app_title}'"
|
||||||
|
|
||||||
|
|
||||||
|
def dialog_title(text: str) -> str:
|
||||||
|
return f"{text} - {QCoreApplication.instance().applicationName()}"
|
||||||
|
|
||||||
|
|
||||||
|
class BaseDialog(QDialog):
|
||||||
|
|
||||||
|
def __init__(self, parent=None):
|
||||||
|
super(BaseDialog, self).__init__(parent=parent)
|
||||||
|
self.setAttribute(Qt.WA_DeleteOnClose, True)
|
||||||
|
self.setWindowFlags(Qt.Dialog | Qt.CustomizeWindowHint | Qt.WindowTitleHint)
|
||||||
|
self.setWindowModality(Qt.WindowModal)
|
||||||
|
|
||||||
|
def setWindowTitle(self, a0):
|
||||||
|
super().setWindowTitle(dialog_title(a0))
|
||||||
|
|
||||||
|
def exec(self):
|
||||||
|
raise RuntimeError(f"Don't use `exec()` with {type(self).__name__}")
|
||||||
|
|
||||||
|
def exec_(self):
|
||||||
|
raise RuntimeError(f"Don't use `exec_()` with {type(self).__name__}")
|
||||||
|
|
||||||
|
# lk: because you will eventually find yourself back here.
|
||||||
|
# on QDialogs the Esc key closes the dialog through keyPressEvent(),
|
||||||
|
# which ultimately call `reject()`. Pressing the Enter/Return button
|
||||||
|
# is a shortcut for pressing the default button and thus calling `accept()`
|
||||||
|
# In turn both `accept()` and `reject()` evetually call `done()`.
|
||||||
|
|
||||||
|
# In the base dialog ignore both. In the subclasses, call the method
|
||||||
|
# from QDialog if required, not this one.
|
||||||
|
# `super(BaseDialog, self).keyPressEvent(a0)`
|
||||||
|
def keyPressEvent(self, a0: QKeyEvent) -> None:
|
||||||
|
if a0.matches(QKeySequence.Cancel):
|
||||||
|
a0.ignore()
|
||||||
|
return
|
||||||
|
if a0.key() == Qt.Key_Enter or a0.key() == Qt.Key_Return:
|
||||||
|
a0.ignore()
|
||||||
|
return
|
||||||
|
super().keyPressEvent(a0)
|
||||||
|
|
||||||
|
# Using the 'X' button on the window manager comes directly here.
|
||||||
|
# It is a spontaneous event so simply ignore it.
|
||||||
|
def closeEvent(self, a0: QCloseEvent) -> None:
|
||||||
|
if a0.spontaneous():
|
||||||
|
a0.ignore()
|
||||||
|
return
|
||||||
|
super().closeEvent(a0)
|
||||||
|
|
||||||
|
|
||||||
|
class ButtonDialog(BaseDialog):
|
||||||
|
|
||||||
|
def __init__(self, parent=None):
|
||||||
|
super(ButtonDialog, self).__init__(parent=parent)
|
||||||
|
|
||||||
|
self.reject_button = QPushButton(self)
|
||||||
|
self.reject_button.setText(self.tr("Cancel"))
|
||||||
|
self.reject_button.setIcon(icon("fa.remove"))
|
||||||
|
self.reject_button.setAutoDefault(False)
|
||||||
|
self.reject_button.clicked.connect(self.reject)
|
||||||
|
|
||||||
|
self.accept_button = QPushButton(self)
|
||||||
|
self.accept_button.setAutoDefault(False)
|
||||||
|
self.accept_button.clicked.connect(self.accept)
|
||||||
|
|
||||||
|
self.button_layout = QHBoxLayout()
|
||||||
|
self.button_layout.addWidget(self.reject_button)
|
||||||
|
self.button_layout.addStretch(20)
|
||||||
|
self.button_layout.addStretch(1)
|
||||||
|
self.button_layout.addWidget(self.accept_button)
|
||||||
|
|
||||||
|
self.main_layout = QVBoxLayout(self)
|
||||||
|
# lk: dirty way to set a minimum width with fixed size constraint
|
||||||
|
spacer = QSpacerItem(
|
||||||
|
480, self.main_layout.spacing(),
|
||||||
|
QSizePolicy.Expanding, QSizePolicy.Fixed
|
||||||
|
)
|
||||||
|
self.main_layout.addItem(spacer)
|
||||||
|
self.main_layout.addLayout(self.button_layout)
|
||||||
|
self.main_layout.setSizeConstraint(QLayout.SetFixedSize)
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
raise RuntimeError(f"Don't use `close()` with {type(self).__name__}")
|
||||||
|
|
||||||
|
def setCentralWidget(self, widget: QWidget):
|
||||||
|
widget.layout().setContentsMargins(0, 0, 0, 0)
|
||||||
|
self.main_layout.insertWidget(0, widget)
|
||||||
|
|
||||||
|
def setCentralLayout(self, layout: QLayout):
|
||||||
|
layout.setContentsMargins(0, 0, 0, 0)
|
||||||
|
self.main_layout.insertLayout(0, layout)
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def accept_handler(self):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def reject_handler(self):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def done_handler(self):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
# These only apply to QDialog. If we move to QWidget for embedded dialogs
|
||||||
|
# we have to use close() and custom handling.
|
||||||
|
|
||||||
|
# lk: Override accept to run our abstract handling method
|
||||||
|
def accept(self):
|
||||||
|
self.accept_handler()
|
||||||
|
super().accept()
|
||||||
|
|
||||||
|
# lk: Override reject to run our abstract handling method
|
||||||
|
def reject(self):
|
||||||
|
self.reject_handler()
|
||||||
|
super().reject()
|
||||||
|
|
||||||
|
# lk: Override `done()` to to run our abstract handling method
|
||||||
|
def done(self, a0):
|
||||||
|
self.done_handler()
|
||||||
|
super().done(a0)
|
||||||
|
|
||||||
|
# lk: Ignore BaseDialog::keyPressEvent and call QDialog::keyPressEvent
|
||||||
|
# because we handle accept and reject here.
|
||||||
|
def keyPressEvent(self, a0: QKeyEvent) -> None:
|
||||||
|
super(BaseDialog, self).keyPressEvent(a0)
|
||||||
|
|
||||||
|
# lk: Ignore BaseDialog::closeEvent and call QDialog::closeEvent
|
||||||
|
# because we handle accept and reject here.
|
||||||
|
def closeEvent(self, a0: QCloseEvent) -> None:
|
||||||
|
super(BaseDialog, self).closeEvent(a0)
|
||||||
|
|
||||||
|
|
||||||
|
class ActionDialog(ButtonDialog):
|
||||||
|
def __init__(self, parent=None):
|
||||||
|
super(ActionDialog, self).__init__(parent=parent)
|
||||||
|
self.__reject_close = False
|
||||||
|
|
||||||
|
self.action_button = QPushButton(self)
|
||||||
|
self.action_button.setAutoDefault(True)
|
||||||
|
self.action_button.clicked.connect(self.action)
|
||||||
|
|
||||||
|
self.button_layout.insertWidget(2, self.action_button)
|
||||||
|
|
||||||
|
def active(self) -> bool:
|
||||||
|
return self.__reject_close
|
||||||
|
|
||||||
|
def setActive(self, active: bool):
|
||||||
|
self.reject_button.setDisabled(active)
|
||||||
|
self.action_button.setDisabled(active)
|
||||||
|
self.accept_button.setDisabled(active)
|
||||||
|
self.__reject_close = active
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def action_handler(self):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
@pyqtSlot()
|
||||||
|
def action(self):
|
||||||
|
self.setActive(True)
|
||||||
|
self.action_handler()
|
||||||
|
|
||||||
|
# lk: Ignore all key presses if there is an ongoing action
|
||||||
|
def keyPressEvent(self, a0: QKeyEvent) -> None:
|
||||||
|
if self.__reject_close:
|
||||||
|
a0.ignore()
|
||||||
|
return
|
||||||
|
super(BaseDialog, self).keyPressEvent(a0)
|
||||||
|
|
||||||
|
# lk: Ignore all closeEvents if there is an ongoing action
|
||||||
|
def closeEvent(self, a0: QCloseEvent) -> None:
|
||||||
|
if self.__reject_close:
|
||||||
|
a0.ignore()
|
||||||
|
return
|
||||||
|
super(BaseDialog, self).closeEvent(a0)
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = ["dialog_title", "dialog_title_game", "BaseDialog", "ButtonDialog", "ActionDialog"]
|
||||||
|
|
||||||
|
|
||||||
|
class TestDialog(BaseDialog):
|
||||||
|
def __init__(self, parent=None):
|
||||||
|
super(TestDialog, self).__init__(parent=parent)
|
||||||
|
|
||||||
|
self.accept_button = QPushButton("accept", self)
|
||||||
|
self.reject_button = QPushButton("reject", self)
|
||||||
|
self.action_button = QPushButton("action", self)
|
||||||
|
self.button_box = QDialogButtonBox(Qt.Horizontal, self)
|
||||||
|
self.button_box.addButton(self.accept_button, QDialogButtonBox.AcceptRole)
|
||||||
|
self.button_box.addButton(self.reject_button, QDialogButtonBox.RejectRole)
|
||||||
|
self.button_box.addButton(self.action_button, QDialogButtonBox.ActionRole)
|
||||||
|
|
||||||
|
self.button_box.accepted.connect(self.accept)
|
||||||
|
self.button_box.rejected.connect(self.reject)
|
||||||
|
|
||||||
|
layout = QVBoxLayout(self)
|
||||||
|
layout.addWidget(self.button_box)
|
||||||
|
|
||||||
|
self.setMinimumWidth(480)
|
||||||
|
|
||||||
|
def setWindowTitle(self, a0):
|
||||||
|
super().setWindowTitle(dialog_title(a0))
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
print("in close")
|
||||||
|
super().close()
|
||||||
|
|
||||||
|
def closeEvent(self, a0: QCloseEvent) -> None:
|
||||||
|
print("in closeEvent")
|
||||||
|
if a0.spontaneous():
|
||||||
|
print("is spontaneous")
|
||||||
|
a0.ignore()
|
||||||
|
return
|
||||||
|
if self.reject_close:
|
||||||
|
a0.ignore()
|
||||||
|
else:
|
||||||
|
self._on_close()
|
||||||
|
super().closeEvent(a0)
|
||||||
|
# super().closeEvent(a0)
|
||||||
|
|
||||||
|
def done(self, a0):
|
||||||
|
print(f"in done {a0}")
|
||||||
|
return
|
||||||
|
super().done(a0)
|
||||||
|
|
||||||
|
def accept(self):
|
||||||
|
print("in accept")
|
||||||
|
self._on_accept()
|
||||||
|
# return
|
||||||
|
# super().accept()
|
||||||
|
|
||||||
|
def reject(self):
|
||||||
|
print("in reject")
|
||||||
|
self._on_reject()
|
||||||
|
# return
|
||||||
|
# super().reject()
|
||||||
|
|
||||||
|
def _on_close(self):
|
||||||
|
print("in _on_close")
|
||||||
|
|
||||||
|
def _on_accept(self):
|
||||||
|
print("in _on_accepted")
|
||||||
|
# self.close()
|
||||||
|
|
||||||
|
def _on_reject(self):
|
||||||
|
print("in _on_rejected")
|
||||||
|
self.close()
|
||||||
|
|
||||||
|
def keyPressEvent(self, a0: QKeyEvent) -> None:
|
||||||
|
super(BaseDialog, self).keyPressEvent(a0)
|
||||||
|
|
||||||
|
|
||||||
|
def test_dialog():
|
||||||
|
app = QApplication(sys.argv)
|
||||||
|
dlg = TestDialog(None)
|
||||||
|
dlg.show()
|
||||||
|
ret = app.exec()
|
||||||
|
sys.exit(ret)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
test_dialog()
|
|
@ -4,4 +4,5 @@ QtAwesome
|
||||||
setuptools
|
setuptools
|
||||||
legendary-gl>=0.20.34
|
legendary-gl>=0.20.34
|
||||||
orjson
|
orjson
|
||||||
|
vdf; platform_system != "Windows"
|
||||||
pywin32; platform_system == "Windows"
|
pywin32; platform_system == "Windows"
|
||||||
|
|
Loading…
Reference in a new issue