Source code for radioviz.tools.base_tool
# Copyright 2025–2026 European Union
# Author: Bulgheroni Antonio (antonio.bulgheroni@ec.europa.eu)
# SPDX-License-Identifier: EUPL-1.2
"""
Base tool definition for the radioviz application.
This module defines the base classes and structures used to implement tools
within the radioviz application framework. It provides the foundational
abstractions for creating tools that can be integrated into the main
application window, including support for analysis actions, context menu
actions, and dockable views.
"""
from __future__ import annotations
from dataclasses import dataclass
from typing import TYPE_CHECKING, Any, Generic, Optional
from PySide6.QtGui import QAction
from PySide6.QtWidgets import QWidget
from radioviz.models.overlays import OverlaySpec
from radioviz.services.typing_helpers import require_not_none
from radioviz.services.window_factory import WindowSpec
from radioviz.services.workspace_manager import ToolWorkspace
from radioviz.tools.tool_api import T_Tool_Controller
if TYPE_CHECKING:
from radioviz.tools.tool_api import ToolContext
[docs]
@dataclass
class ToolEvent:
"""
Event structure for tool communication.
This dataclass represents events that can be triggered within the tool
system to communicate between different components of the application.
"""
#: Unique identifier of the tool that triggered the event
tool_id: str
#: Type of event being triggered
event: str
#: Optional payload data associated with the event
payload: Any = None
[docs]
class Tool(Generic[T_Tool_Controller]):
"""
Base class for defining application tools.
This class serves as the foundation for implementing various tools within
the radioviz application. Each tool should inherit from this base class
and implement the required methods to integrate with the application's
UI and functionality.
The tool instance is created once per application run and contains
metadata about the tool along with registration information for windows
and overlays. It does not contain any view-specific logic.
"""
#: Unique identifier of the tool
tool_id: str = 'base'
#: Human-readable name
name: str = 'Base Tool'
#: Tooltip or description
description: str = ''
#: List of window specifications to register
windows_to_be_registered: list[WindowSpec] = []
#: List of overlay specifications to register
overlays_to_be_registered: list[OverlaySpec] = []
def __init__(self) -> None:
self._controller: Optional[T_Tool_Controller] = None
self._restore_spec: Optional[ToolWorkspace] = None
[docs]
def _require_restore_spec(self) -> ToolWorkspace:
"""
Return the workspace spec used for restoration or raise if missing.
:return: The workspace specification for this restore
:rtype: ToolWorkspace
:raises RuntimeError: If the restore spec has not been set
"""
return require_not_none(self._restore_spec, f'{self.tool_id} restore spec')
[docs]
def create_controller(self, ctx: ToolContext) -> T_Tool_Controller:
"""
Create a controller instance for this tool.
This method must be implemented by subclasses to provide a concrete
controller implementation that manages the tool's behavior and state.
:param ctx: The tool context containing application state and services
:type ctx: ToolContext
:return: A controller instance for managing the tool
:rtype: ToolController[Any, Any]
:raise NotImplementedError: Always raised by the base implementation
"""
raise NotImplementedError
# ---- Menu items -----------------------------------------------------
[docs]
def create_analysis_action(self, parent: QWidget, controller: T_Tool_Controller) -> Optional[QAction]:
"""
Create an action for the main window 'Analysis' menu.
This method creates a menu action that will appear in the main window's
Analysis menu. Tools that don't expose a trigger action should return None.
:param parent: The parent widget for the action
:type parent: QWidget
:param controller: The tool controller instance
:type controller: ToolController[Any, Any]
:return: A QAction instance or None if no action is needed
:rtype: QAction or None
"""
return None