update: fixed systemwide profile popup on app closing

This commit is contained in:
JOhn 2026-07-18 08:31:28 -04:00
parent d52ca4842c
commit ab23fc958e

View file

@ -12,12 +12,13 @@ from PyQt6.QtWidgets import (
QApplication, QMainWindow, QStackedWidget, QLabel, QPushButton,
QDialog, QVBoxLayout, QHBoxLayout, QMessageBox
)
from PyQt6.QtGui import QPixmap, QFont, QFontDatabase, QIcon
from PyQt6.QtGui import QPixmap, QFont, QFontDatabase
from PyQt6 import QtGui
from PyQt6.QtCore import Qt, QTimer, QEvent
from core.Constants import Constants
from core.controllers.ConfigurationController import ConfigurationController
from core.controllers.ProfileController import ProfileController
from core.Errors import UnknownConnectionTypeError
from core.errors.logger import logger as core_logger
@ -64,7 +65,6 @@ from gui.v2.actions.ticket_failure import (
clear_ticket_verification_failure,
)
from gui.v2.actions.should_be_synchronized import should_be_synchronized
from gui.v2.ui.popups.message_box import style_message_box, mark_confirm_button
class CustomWindow(QMainWindow):
@ -76,8 +76,7 @@ class CustomWindow(QMainWindow):
gui_dir = os.path.dirname(os.path.abspath(__file__))
font_path = os.path.join(gui_dir, 'resources', 'fonts')
# # Get's SQLAlchemy going,
# orm.start()
orm.start()
retro_gaming_path = os.path.join(font_path, 'retro-gaming.ttf')
font_id = QFontDatabase.addApplicationFont(retro_gaming_path)
@ -129,6 +128,9 @@ class CustomWindow(QMainWindow):
self.animation_step = 0
self.page_history = []
self.log_path = None
self._close_confirmation_pending = False
self._close_disconnect_in_progress = False
self._closing_after_disconnect = False
self.setFixedSize(800, 570)
@ -628,18 +630,95 @@ class CustomWindow(QMainWindow):
def closeEvent(self, event=None):
core_logger.info("HydraVeil application closing")
# Close SQLAlchemy,
if self._closing_after_disconnect:
orm.stop()
if event is not None:
event.accept()
return
connected_profiles = self.connection_manager.get_connected_profiles()
if self._close_confirmation_pending or self._close_disconnect_in_progress:
if event is not None:
event.ignore()
return
connected_profiles = self._get_enabled_profile_ids()
if connected_profiles:
self.update_status('Profiles are still connected (disconnect flow lands in Chunk 9).')
if event is not None:
event.accept()
else:
if event is not None:
event.ignore()
self._show_close_disconnect_confirmation(connected_profiles)
return
orm.stop()
if event is not None:
event.accept()
def _get_enabled_profile_ids(self):
try:
profiles = ProfileController.get_all()
except Exception:
return self.connection_manager.get_connected_profiles()
connected_profiles = []
self.connection_manager._connected_profiles.clear()
for profile_id, profile in profiles.items():
try:
if ProfileController.is_enabled(profile):
connected_profiles.append(profile_id)
self.connection_manager.add_connected_profile(profile_id)
except Exception:
pass
return connected_profiles
def _show_close_disconnect_confirmation(self, connected_profiles):
from gui.v2.ui.popups.confirmation_popup import ConfirmationPopup
self._close_confirmation_pending = True
message = self._create_close_disconnect_message(connected_profiles)
self.popup = ConfirmationPopup(
self, message=message, action_button_text="Exit", cancel_button_text="Cancel")
self.popup.setWindowModality(Qt.WindowModality.ApplicationModal)
self.popup.setAttribute(Qt.WidgetAttribute.WA_DeleteOnClose)
self.popup.finished.connect(
lambda result: self._handle_close_disconnect_result(result, connected_profiles))
self.popup.destroyed.connect(
lambda *_: self._handle_close_disconnect_popup_closed())
self.popup.show()
def _create_close_disconnect_message(self, connected_profiles):
profile_numbers = ', '.join(str(profile_id)
for profile_id in connected_profiles)
is_are = "is" if len(connected_profiles) == 1 else "are"
return f'Profile{"" if len(connected_profiles) == 1 else "s"} {profile_numbers} {is_are} still connected.\nAll connected profiles will be disconnected on exit.\nDo you want to proceed?'
def _handle_close_disconnect_result(self, result, connected_profiles):
self._close_confirmation_pending = False
if not result:
return
self._close_disconnect_in_progress = True
self.update_status('Disabling profiles...')
self.worker_thread = WorkerThread(
'DISABLE_ALL_PROFILES', profile_data=connected_profiles)
self.worker_thread.text_output.connect(self.update_status)
self.worker_thread.finished.connect(self._finish_close_disconnect)
self.worker_thread.start()
def _handle_close_disconnect_popup_closed(self):
if self._close_confirmation_pending:
self._close_confirmation_pending = False
self.popup = None
def _finish_close_disconnect(self, _ok=True):
self._close_disconnect_in_progress = False
connected_profiles = self._get_enabled_profile_ids()
if connected_profiles:
self.update_status('Could not disconnect all profiles. Exit canceled.')
return
self.update_status('All profiles disabled. Bye!')
self._closing_after_disconnect = True
QTimer.singleShot(0, self.close)
def update_image(self, appearance_value="original"):
image_path = os.path.join(self.btn_path, f"{appearance_value}.png")
pixmap = QPixmap(image_path)
@ -816,5 +895,5 @@ class CustomWindow(QMainWindow):
def start_ui(force_sync):
app = QApplication(sys.argv)
window = CustomWindow(force_sync)
window = CustomWindow(force_sync=force_sync)
sys.exit(app.exec())