# Copyright 2025–2026 European Union
# Author: Bulgheroni Antonio (antonio.bulgheroni@ec.europa.eu)
# SPDX-License-Identifier: EUPL-1.2
"""
Sub-window view module for the radioviz application.
This module provides the :class:`SubWindow` class which implements a
custom MDI sub-window for the application's main window. It handles
window management events and integrates with the controller pattern
to manage the sub-window's behavior.
"""
from __future__ import annotations
from typing import TYPE_CHECKING, Any, Generic, Optional, TypeVar
import PySide6
from PySide6.QtCore import Qt, Signal
from PySide6.QtWidgets import QMdiSubWindow, QWidget
from radioviz.services.application_services import ApplicationServices
from radioviz.services.workspace_manager import WindowState
if TYPE_CHECKING:
from radioviz.controllers.sub_window_controller import SubWindowController
T_SubWindowController = TypeVar('T_SubWindowController', bound='SubWindowController[Any]')
[docs]
class SubWindow(QMdiSubWindow, Generic[T_SubWindowController]):
"""
Custom MDI sub-window implementation for the radioviz application.
This class extends :class:`QMdiSubWindow` to provide specialized
functionality for sub-windows within the application's MDI interface.
It manages the connection between the view and controller components
and handles window closing events.
.. note::
The signal payload is ``(global_pos, controller)``.
:ivar about_to_close: Signal emitted when the sub-window is about to close
:vartype about_to_close: Signal
:ivar context_menu_requested: Signal emitted when a context menu is requested
:vartype context_menu_requested: Signal
"""
about_to_close = Signal(object)
context_menu_requested = Signal(object, object)
def __init__(self, controller: T_SubWindowController, parent: Optional[QWidget] = None):
"""
Initialize the sub-window view.
:param controller: The controller instance managing this sub-window
:type controller: SubWindowController[Any]
:param parent: Parent widget for this sub-window
:type parent: Optional[QWidget]
"""
super().__init__(parent=parent)
self.controller = controller
self.controller.set_view(self)
self.application_services = ApplicationServices()
[docs]
def closeEvent(self, e: 'PySide6.QtGui.QCloseEvent') -> None:
"""
Handle the close event for the sub-window.
This method is called when the user attempts to close the sub-window.
It emits the :attr:`about_to_close` signal before calling the parent
close event handler.
:param e: The close event object
:type e: PySide6.QtGui.QCloseEvent
"""
super().closeEvent(e)
self.about_to_close.emit(self) # it sends a view, not a controller!
[docs]
def on_data_state_changed(self) -> None:
"""
Placeholder method for handling data state changes.
This method is currently a stub and does nothing. It is intended to be
overridden by subclasses to implement specific behavior when data state
changes occur.
"""
pass
[docs]
def window_state(self) -> WindowState:
"""
Get the current window state.
This method retrieves the current window state by checking the window's
state flags and returns the corresponding :class:`WindowState` enum value.
:return: The current window state
:rtype: WindowState
"""
state = self.windowState()
if state & Qt.WindowState.WindowMinimized:
return WindowState.Minimized
elif state & Qt.WindowState.WindowMaximized:
return WindowState.Maximized
elif state & Qt.WindowState.WindowFullScreen:
return WindowState.FullScreen
else:
return WindowState.Normal
[docs]
def set_window_state(self, state: WindowState) -> None:
"""
Set the window state to the specified state.
This method sets the window's state based on the provided :class:`WindowState`
enum value. It calls the appropriate Qt show methods to achieve the desired
window state.
:param state: The window state to set
:type state: WindowState
"""
if state == WindowState.Minimized:
self.showMinimized()
elif state == WindowState.Maximized:
self.showMaximized()
elif state == WindowState.FullScreen:
self.showFullScreen()
else:
self.showNormal()