diff --git a/bec_widgets/applications/launch_window.py b/bec_widgets/applications/launch_window.py index d3597ac7..e87ddf46 100644 --- a/bec_widgets/applications/launch_window.py +++ b/bec_widgets/applications/launch_window.py @@ -235,10 +235,8 @@ class LaunchWindow(BECMainWindow): raise ValueError( f"Name {name} must be unique for dock areas, but already exists: {existing_dock_areas}." ) - if not WidgetContainerUtils.has_name_valid_chars(name): - raise ValueError( - f"Name {name} contains invalid characters. Only alphanumeric characters, underscores, and dashes are allowed." - ) + WidgetContainerUtils.raise_for_invalid_name(name) + else: name = "dock_area" name = WidgetContainerUtils.generate_unique_name(name, existing_dock_areas) @@ -284,6 +282,8 @@ class LaunchWindow(BECMainWindow): raise ValueError("UI file must be provided for custom UI file launch.") filename = os.path.basename(ui_file).split(".")[0] + WidgetContainerUtils.raise_for_invalid_name(filename) + tree = ET.parse(ui_file) root = tree.getroot() # Check if the top-level widget is a QMainWindow diff --git a/bec_widgets/utils/container_utils.py b/bec_widgets/utils/container_utils.py index f2c2f950..c8932f0e 100644 --- a/bec_widgets/utils/container_utils.py +++ b/bec_widgets/utils/container_utils.py @@ -1,11 +1,10 @@ from __future__ import annotations -import itertools -from typing import Literal, Type +from typing import Any, Type from qtpy.QtWidgets import QWidget -from bec_widgets.cli.rpc.rpc_register import RPCRegister +from bec_widgets.cli.client_utils import BECGuiClient class WidgetContainerUtils: @@ -73,3 +72,36 @@ class WidgetContainerUtils: return None else: raise ValueError(f"No widget of class {widget_class} found.") + + @staticmethod + def name_is_protected(name: str, container: Any = None) -> bool: + """ + Check if the name is not protected. + + Args: + name(str): The name to be checked. + + Returns: + bool: True if the name is not protected, False otherwise. + """ + if container is None: + container = BECGuiClient + gui_client_methods = set(filter(lambda x: not x.startswith("_"), dir(container))) + return name in gui_client_methods + + @staticmethod + def raise_for_invalid_name(name: str, container: Any = None) -> None: + """ + Check if the name is valid. If not, raise a ValueError. + + Args: + name(str): The name to be checked. + Raises: + ValueError: If the name is not valid. + """ + if not WidgetContainerUtils.has_name_valid_chars(name): + raise ValueError( + f"Name '{name}' contains invalid characters. Only alphanumeric characters, underscores, and dashes are allowed." + ) + if WidgetContainerUtils.name_is_protected(name, container): + raise ValueError(f"Name '{name}' is protected. Please choose another name.") diff --git a/bec_widgets/widgets/containers/dock/dock.py b/bec_widgets/widgets/containers/dock/dock.py index ed0271d3..20318dfb 100644 --- a/bec_widgets/widgets/containers/dock/dock.py +++ b/bec_widgets/widgets/containers/dock/dock.py @@ -303,11 +303,7 @@ class BECDock(BECWidget, Dock): shift(Literal["down", "up", "left", "right"]): The direction to shift the widgets if the position is occupied. """ if name is not None: - if not WidgetContainerUtils.has_name_valid_chars(name): - raise ValueError( - f"Name {name} contains invalid characters. " - f"Only alphanumeric characters and underscores are allowed." - ) + WidgetContainerUtils.raise_for_invalid_name(name, container=self) if row is None: row = self.layout.rowCount() diff --git a/bec_widgets/widgets/containers/dock/dock_area.py b/bec_widgets/widgets/containers/dock/dock_area.py index e8d06e19..ac9df021 100644 --- a/bec_widgets/widgets/containers/dock/dock_area.py +++ b/bec_widgets/widgets/containers/dock/dock_area.py @@ -366,11 +366,8 @@ class BECDockArea(BECWidget, QWidget): f"Name {name} must be unique for docks, but already exists in DockArea " f"with name: {self.object_name} and id {self.gui_id}." ) - if not WidgetContainerUtils.has_name_valid_chars(name): - raise ValueError( - f"Name {name} contains invalid characters. " - f"Only alphanumeric characters and underscores are allowed." - ) + WidgetContainerUtils.raise_for_invalid_name(name, container=self) + else: # Name is not provided name = WidgetContainerUtils.generate_unique_name(name="dock", list_of_names=dock_names)