diff --git a/rare/components/__init__.py b/rare/components/__init__.py index f5af6d2d..8df9e34f 100644 --- a/rare/components/__init__.py +++ b/rare/components/__init__.py @@ -55,14 +55,9 @@ class Rare(RareApp): self.launch_dialog: Optional[LaunchDialog] = None self.timer: Optional[QTimer] = None - # launch app - self.launch_dialog = LaunchDialog(parent=None) - self.launch_dialog.quit_app.connect(self.launch_dialog.close) - self.launch_dialog.quit_app.connect(lambda x: sys.exit(x)) - self.launch_dialog.start_app.connect(self.start_app) - self.launch_dialog.start_app.connect(self.launch_dialog.close) - - self.launch_dialog.login() + # This launches the application after it has been instantiated. + # The timer's signal will be serviced once we call `exec()` on the application + QTimer.singleShot(0, self.launch_app) def poke_timer(self): dt_exp = datetime.fromisoformat(self.core.lgd.userdata['expires_at'][:-1]).replace(tzinfo=timezone.utc) @@ -80,13 +75,23 @@ class Rare(RareApp): return self.poke_timer() + @pyqtSlot() + def launch_app(self): + self.launch_dialog = LaunchDialog(parent=None) + self.launch_dialog.exit_app.connect(self.launch_dialog.close) + self.launch_dialog.exit_app.connect(self.__on_exit_app) + self.launch_dialog.start_app.connect(self.start_app) + self.launch_dialog.start_app.connect(self.launch_dialog.close) + self.launch_dialog.login() + + @pyqtSlot() def start_app(self): self.timer = QTimer() self.timer.timeout.connect(self.re_login) self.poke_timer() self.main_window = MainWindow() - self.main_window.exit_app.connect(self.on_exit_app) + self.main_window.exit_app.connect(self.__on_exit_app) if not self.args.silent: self.main_window.show() @@ -94,11 +99,11 @@ class Rare(RareApp): if self.args.test_start: self.main_window.close() self.main_window = None - self.on_exit_app(0) + self.__on_exit_app(0) @pyqtSlot() @pyqtSlot(int) - def on_exit_app(self, exit_code=0): + def __on_exit_app(self, exit_code=0): threadpool = QThreadPool.globalInstance() threadpool.waitForDone() if self.timer is not None: @@ -119,9 +124,7 @@ def start(args) -> int: QApplication.setAttribute(Qt.AA_EnableHighDpiScaling, True) QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps, True) app = Rare(args) - exit_code = app.exec_() - # if not restart - # restart app + exit_code = app.exec() del app if exit_code != -133742: break diff --git a/rare/components/dialogs/launch_dialog.py b/rare/components/dialogs/launch_dialog.py index ee81fd12..ead7ac9d 100644 --- a/rare/components/dialogs/launch_dialog.py +++ b/rare/components/dialogs/launch_dialog.py @@ -14,7 +14,7 @@ logger = getLogger("LaunchDialog") class LaunchDialog(QDialog): - quit_app = pyqtSignal(int) + exit_app = pyqtSignal(int) start_app = pyqtSignal() def __init__(self, parent=None): @@ -74,7 +74,7 @@ class LaunchDialog(QDialog): self.show() self.launch() else: - self.quit_app.emit(0) + self.exit_app.emit(0) def launch(self): self.progress_info.setText(self.tr("Preparing Rare")) diff --git a/rare/components/dialogs/login/__init__.py b/rare/components/dialogs/login/__init__.py index 66a1f346..f9ca2b59 100644 --- a/rare/components/dialogs/login/__init__.py +++ b/rare/components/dialogs/login/__init__.py @@ -1,7 +1,6 @@ -from dataclasses import dataclass from logging import getLogger -from PyQt5.QtCore import Qt +from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot from PyQt5.QtWidgets import QLayout, QDialog, QMessageBox, QFrame from legendary.core import LegendaryCore @@ -15,13 +14,6 @@ from .import_login import ImportLogin logger = getLogger("LoginDialog") -@dataclass -class LoginPages: - landing: int - browser: int - import_egl: int - - class LandingPage(QFrame): def __init__(self, parent=None): super(LandingPage, self).__init__(parent=parent) @@ -31,8 +23,7 @@ class LandingPage(QFrame): class LoginDialog(QDialog): - logged_in: bool = False - pages = LoginPages(landing=0, browser=1, import_egl=2) + exit_app: pyqtSignal = pyqtSignal(int) def __init__(self, core: LegendaryCore, parent=None): super(LoginDialog, self).__init__(parent=parent) @@ -51,6 +42,8 @@ class LoginDialog(QDialog): self.ui = Ui_LoginDialog() self.ui.setupUi(self) + self.logged_in: bool = False + self.core = core self.args = ArgumentsSingleton() @@ -59,16 +52,16 @@ class LoginDialog(QDialog): self.ui.login_stack_layout.addWidget(self.login_stack) self.landing_page = LandingPage(self.login_stack) - self.login_stack.insertWidget(self.pages.landing, self.landing_page) + self.login_stack.insertWidget(0, self.landing_page) self.browser_page = BrowserLogin(self.core, self.login_stack) - self.login_stack.insertWidget(self.pages.browser, self.browser_page) + self.login_stack.insertWidget(1, self.browser_page) self.browser_page.success.connect(self.login_successful) self.browser_page.changed.connect( lambda: self.ui.next_button.setEnabled(self.browser_page.is_valid()) ) self.import_page = ImportLogin(self.core, self.login_stack) - self.login_stack.insertWidget(self.pages.import_egl, self.import_page) + self.login_stack.insertWidget(2, self.import_page) self.import_page.success.connect(self.login_successful) self.import_page.changed.connect(lambda: self.ui.next_button.setEnabled(self.import_page.is_valid())) @@ -84,34 +77,34 @@ class LoginDialog(QDialog): self.ui.back_button.clicked.connect(self.back_clicked) self.ui.next_button.clicked.connect(self.next_clicked) - self.login_stack.setCurrentIndex(self.pages.landing) + self.login_stack.setCurrentWidget(self.landing_page) self.layout().setSizeConstraint(QLayout.SetFixedSize) def back_clicked(self): self.ui.back_button.setEnabled(False) self.ui.next_button.setEnabled(True) - self.login_stack.slideInIndex(self.pages.landing) + self.login_stack.slideInWidget(self.landing_page) def browser_radio_clicked(self): - self.login_stack.slideInIndex(self.pages.browser) + self.login_stack.slideInWidget(self.browser_page) self.ui.back_button.setEnabled(True) self.ui.next_button.setEnabled(False) def import_radio_clicked(self): - self.login_stack.slideInIndex(self.pages.import_egl) + self.login_stack.slideInWidget(self.import_page) self.ui.back_button.setEnabled(True) self.ui.next_button.setEnabled(self.import_page.is_valid()) def next_clicked(self): - if self.login_stack.currentIndex() == self.pages.landing: + if self.login_stack.currentWidget() is self.landing_page: if self.landing_page.ui.login_browser_radio.isChecked(): self.browser_radio_clicked() if self.landing_page.ui.login_import_radio.isChecked(): self.import_radio_clicked() - elif self.login_stack.currentIndex() == self.pages.browser: + elif self.login_stack.currentWidget() is self.browser_page: self.browser_page.do_login() - elif self.login_stack.currentIndex() == self.pages.import_egl: + elif self.login_stack.currentWidget() is self.import_page: self.import_page.do_login() def login(self): diff --git a/rare/components/main_window.py b/rare/components/main_window.py index 1efd4f66..318fc6b6 100644 --- a/rare/components/main_window.py +++ b/rare/components/main_window.py @@ -44,7 +44,7 @@ class MainWindow(QMainWindow): self.setWindowTitle("Rare - GUI for legendary") self.tab_widget = MainTabWidget(self) - self.tab_widget.exit_app.connect(self.on_exit_app) + self.tab_widget.exit_app.connect(self.__on_exit_app) self.setCentralWidget(self.tab_widget) # Set up status bar stuff (jumping through a lot of hoops) @@ -112,7 +112,7 @@ class MainWindow(QMainWindow): self.timer.start() self.tray_icon: TrayIcon = TrayIcon(self) - self.tray_icon.exit_app.connect(self.on_exit_app) + self.tray_icon.exit_app.connect(self.__on_exit_app) self.tray_icon.show_app.connect(self.show) self.tray_icon.activated.connect(lambda r: self.toggle() if r == self.tray_icon.DoubleClick else None) @@ -203,7 +203,7 @@ class MainWindow(QMainWindow): @pyqtSlot() @pyqtSlot(int) - def on_exit_app(self, exit_code=0) -> None: + def __on_exit_app(self, exit_code=0) -> None: self.__exit_code = exit_code self.close() diff --git a/rare/components/tabs/__init__.py b/rare/components/tabs/__init__.py index 91a6d177..697984a6 100644 --- a/rare/components/tabs/__init__.py +++ b/rare/components/tabs/__init__.py @@ -51,7 +51,7 @@ class MainTabWidget(QTabWidget): self.setTabEnabled(button_index, False) self.account_widget = AccountWidget(self) - self.account_widget.logout.connect(self.logout) + self.account_widget.exit_app.connect(self.__on_exit_app) account_action = QWidgetAction(self) account_action.setDefaultWidget(self.account_widget) account_button = TabButtonWidget("mdi.account-circle", "Account", fallback_icon="fa.user") @@ -93,25 +93,28 @@ class MainTabWidget(QTabWidget): self.tab_bar.setMinimumWidth(self.width()) super(MainTabWidget, self).resizeEvent(event) - @pyqtSlot() - def logout(self): + @pyqtSlot(int) + def __on_exit_app(self, exit_code: int): # FIXME: Don't allow logging out if there are active downloads if self.downloads_tab.is_download_active: QMessageBox.warning( self, - self.tr("Logout"), - self.tr("There are active downloads. Stop them before logging out."), + self.tr("Quit") if exit_code == self.account_widget.ExitCodes.EXIT else self.tr("Logout"), + self.tr("There are active downloads. Stop them before trying to quit."), ) return # FIXME: End of FIXME - reply = QMessageBox.question( - self, - self.tr("Logout"), - self.tr("Do you really want to logout {}?").format(self.core.lgd.userdata.get("display_name")), - buttons=(QMessageBox.Yes | QMessageBox.No), - defaultButton=QMessageBox.No, - ) + if exit_code == self.account_widget.ExitCodes.LOGOUT: + reply = QMessageBox.question( + self, + self.tr("Logout"), + self.tr("Do you really want to logout {}?").format(self.core.lgd.userdata.get("display_name")), + buttons=(QMessageBox.Yes | QMessageBox.No), + defaultButton=QMessageBox.No, + ) - if reply == QMessageBox.Yes: - self.core.lgd.invalidate_userdata() - self.exit_app.emit(-133742) # restart exit code + if reply == QMessageBox.Yes: + self.core.lgd.invalidate_userdata() + else: + return + self.exit_app.emit(exit_code) # restart exit code diff --git a/rare/components/tabs/account/__init__.py b/rare/components/tabs/account/__init__.py index 91835cce..5806082b 100644 --- a/rare/components/tabs/account/__init__.py +++ b/rare/components/tabs/account/__init__.py @@ -1,15 +1,21 @@ import webbrowser +from enum import IntEnum -from PyQt5.QtCore import pyqtSignal -from PyQt5.QtWidgets import QWidget, QVBoxLayout, QMessageBox, QLabel, QPushButton +from PyQt5.QtCore import pyqtSignal, pyqtSlot +from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QPushButton from rare.shared import LegendaryCoreSingleton, GlobalSignalsSingleton from rare.utils.misc import icon class AccountWidget(QWidget): + exit_app: pyqtSignal = pyqtSignal(int) logout: pyqtSignal = pyqtSignal() + class ExitCodes(IntEnum): + EXIT = 0 + LOGOUT = -133742 + def __init__(self, parent): super(AccountWidget, self).__init__(parent=parent) self.core = LegendaryCoreSingleton() @@ -25,11 +31,22 @@ class AccountWidget(QWidget): "https://www.epicgames.com/account/personal?productName=epicgames" ) ) - self.logout_button = QPushButton(self.tr("Logout")) - self.logout_button.clicked.connect(self.logout) + self.logout_button = QPushButton(self.tr("Logout"), parent=self) + self.logout_button.clicked.connect(self.__on_logout) + self.quit_button = QPushButton(self.tr("Quit"), parent=self) + self.quit_button.clicked.connect(self.__on_quit) layout = QVBoxLayout(self) layout.addWidget(QLabel(self.tr("Account"))) layout.addWidget(QLabel(self.tr("Logged in as {}").format(username))) layout.addWidget(self.open_browser) layout.addWidget(self.logout_button) + layout.addWidget(self.quit_button) + + @pyqtSlot() + def __on_quit(self): + self.exit_app.emit(AccountWidget.ExitCodes.EXIT) + + @pyqtSlot() + def __on_logout(self): + self.exit_app.emit(AccountWidget.ExitCodes.LOGOUT) diff --git a/rare/shared/rare_core.py b/rare/shared/rare_core.py index 69132637..e4cb2a0e 100644 --- a/rare/shared/rare_core.py +++ b/rare/shared/rare_core.py @@ -179,8 +179,8 @@ class RareCore(QObject): del self.__args self.__args = None + del self.__eos_overlay RareCore.__instance = None - super(RareCore, self).deleteLater() def __validate_install(self, rgame: RareGame):