# Copyright 2026 European Union
# Author: Bulgheroni Antonio (antonio.bulgheroni@ec.europa.eu)
# SPDX-License-Identifier: EUPL-1.2
"""Editor for selecting the user interface defined in a steering file.
:Author: Bulgheroni Antonio (antonio.bulgheroni@ec.europa.eu)
:Description: Allow the user to pick which UI plugin should drive execution.
"""
from __future__ import annotations
from typing import Iterable
from PySide6.QtCore import Signal
from PySide6.QtWidgets import QComboBox, QFormLayout, QLabel, QWidget
from mafw.steering_gui.utils import block_signals
[docs]
class UIEditor(QWidget):
"""Widget that exposes the configured user interface and allows switching it."""
interface_changed = Signal(str)
_loading_text = 'Loading available UIs...'
_empty_text = 'No user interfaces available.'
def __init__(self, parent: QWidget | None = None) -> None:
super().__init__(parent)
self.interface_combo = QComboBox()
layout = QFormLayout()
layout.addRow(QLabel('Select User Interface'), self.interface_combo)
self.setLayout(layout)
self._available_interfaces: tuple[str, ...] | None = None
self._pending_interface: str | None = None
self.interface_combo.currentTextChanged.connect(self._on_interface_changed)
self.set_available_interfaces(None)
[docs]
def set_available_interfaces(self, names: Iterable[str] | None) -> None:
"""Populate the combo box once plugins have produced their UI list."""
self._available_interfaces = None if names is None else tuple(str(name) for name in names)
with block_signals(self.interface_combo):
self.interface_combo.clear()
if self._available_interfaces is None:
label = self._pending_interface or self._loading_text
self.interface_combo.addItem(label)
self.interface_combo.setEnabled(False)
return
if not self._available_interfaces:
label = self._pending_interface or self._empty_text
self.interface_combo.addItem(label)
self.interface_combo.setEnabled(False)
return
self.interface_combo.addItems(self._available_interfaces)
self.interface_combo.setEnabled(True)
self._apply_pending_selection()
[docs]
def set_current_interface(self, interface: str | None) -> None:
"""Request the combobox to display a specific interface without emitting signals."""
self._pending_interface = interface
if not interface or not self._available_interfaces:
return
with block_signals(self.interface_combo):
self._apply_pending_selection()
def _apply_pending_selection(self) -> None:
if not self._pending_interface:
return
index = self.interface_combo.findText(self._pending_interface)
if index == -1 and self.interface_combo.isEnabled():
self.interface_combo.addItem(self._pending_interface)
index = self.interface_combo.findText(self._pending_interface)
if index != -1:
self.interface_combo.setCurrentIndex(index)
def _on_interface_changed(self, text: str) -> None:
if self._available_interfaces and text in self._available_interfaces:
self._pending_interface = text
self.interface_changed.emit(text)