Skip to content

Application State

Observable application runtime state.

Provides a singleton for managing mutable application state with Qt signals for reactive updates. Use this for state that changes during runtime and needs to be observed by multiple components.

from src.shared_services.state.app_state import AppState

# Get singleton
state = AppState.instance()

# Connect to state changes
state.software_changed.connect(self.on_software_changed)

# Update state (emits signal automatically)
state.set_active_software("PlantDesign")

For theme state, use StylesheetManager instead.

API Reference

src.shared_services.state.app_state

Observable application runtime state.

Provides a singleton for managing mutable application state with Qt signals for reactive updates. Use this for state that changes during runtime and needs to be observed by multiple components.

Usage

from src.shared_services.state.app_state import AppState

Get singleton

state = AppState.instance()

Connect to state changes

state.software_changed.connect(self.on_software_changed)

Update state (emits signal automatically)

state.set_active_software("PlantDesign")

Note

For theme state, use StylesheetManager instead: from src.shared_services.rendering.stylesheets.api import StylesheetManager

AppState

Bases: QObject

Singleton managing observable application runtime state.

This class manages mutable state that needs to be shared across the application with change notifications via Qt signals.

Signals

software_changed: Emitted when active software changes. Args: software_name (str), is_active (bool) library_mode_changed: Emitted when library editing mode changes. Args: in_edit_view (bool), in_project_usage (bool) network_status_changed: Emitted when network connectivity changes. Args: connected (bool)

Example

Basic usage::

state = AppState.instance()

# Connect to changes
state.software_changed.connect(self.handle_software_change)

# Set active software
state.set_active_software("PlantDesign")

# Check state
if state.is_software_active:
    print(f"Running: {state.active_software}")
Source code in src\shared_services\state\app_state.py
class AppState(QObject):
    """
    Singleton managing observable application runtime state.

    This class manages mutable state that needs to be shared across
    the application with change notifications via Qt signals.

    Signals:
        software_changed: Emitted when active software changes.
            Args: software_name (str), is_active (bool)
        library_mode_changed: Emitted when library editing mode changes.
            Args: in_edit_view (bool), in_project_usage (bool)
        network_status_changed: Emitted when network connectivity changes.
            Args: connected (bool)

    Example:
        Basic usage::

            state = AppState.instance()

            # Connect to changes
            state.software_changed.connect(self.handle_software_change)

            # Set active software
            state.set_active_software("PlantDesign")

            # Check state
            if state.is_software_active:
                print(f"Running: {state.active_software}")
    """

    software_changed = Signal(str, bool)
    library_mode_changed = Signal(bool)
    library_project_usage_changed = Signal(bool)
    network_status_changed = Signal(bool)

    _instance: Optional["AppState"] = None

    def __init__(self) -> None:
        """Initialize the application state."""
        super().__init__()
        self._active_software: str = ""
        self._software_active: bool = False
        self._library_edit_mode: bool = False
        self._library_in_project_usage: bool = False
        self._network_connected: bool = True
        self._network_override: Optional[bool] = None


    @classmethod
    def instance(cls) -> "AppState":
        """
        Get the singleton instance.

        Returns:
            The shared AppState instance.
        """
        if cls._instance is None:
            cls._instance = cls()
        return cls._instance

    @classmethod
    def reset_instance(cls) -> None:
        """
        Reset the singleton instance.

        Useful for testing to ensure clean state between tests.
        """
        cls._instance = None

    # =========================================================================
    # SOFTWARE STATE
    # =========================================================================

    @property
    def active_software(self) -> str:
        """Get the name of the currently active software module."""
        return self._active_software

    @property
    def is_software_active(self) -> bool:
        """Check if any software module is currently active."""
        return self._software_active

    def set_active_software(self, name: str) -> None:
        """
        Set the active software module.

        Args:
            name: Name of the software module (e.g., "PlantDesign").
                  Empty string clears the active software.

        Emits:
            software_changed: With (name, is_active) arguments.
        """
        self._active_software = name
        self._software_active = bool(name)
        self.software_changed.emit(name, self._software_active)

    def clear_active_software(self) -> None:
        """Clear the active software module."""
        self.set_active_software("")

    # =========================================================================
    # LIBRARY EDIT MODE
    # =========================================================================

    @property
    def is_library_edit_mode(self) -> bool:
        """Check if the library system is in edit view."""
        return self._library_edit_mode

    def set_library_edit_mode(self, in_edit_view: bool) -> None:
        """
        Set the library editing mode state.

        Args:
            in_edit_view: True if editing a library, False otherwise.

        Emits:
            library_mode_changed: With (in_edit_view) argument when state changes.
        """
        if self._library_edit_mode != in_edit_view:
            self._library_edit_mode = in_edit_view
            self.library_mode_changed.emit(in_edit_view)

    # =========================================================================
    # LIBRARY PROJECT USAGE
    # =========================================================================

    @property
    def is_library_in_project_usage(self) -> bool:
        """Check if the library system is being used within a project."""
        return self._library_in_project_usage

    def set_library_in_project_usage(self, active: bool) -> None:
        """
        Set whether the library system is in project usage mode.

        Args:
            active: True if library is used within a project context.

        Emits:
            library_project_usage_changed: With (active) argument when state changes.
        """
        if self._library_in_project_usage != active:
            self._library_in_project_usage = active
            self.library_project_usage_changed.emit(active)

    # =========================================================================
    # NETWORK STATE
    # =========================================================================

    @property
    def is_network_connected(self) -> bool:
        """Check if the network is currently connected."""
        return self._network_connected

    def set_network_connected(self, connected: bool) -> None:
        """
        Set the network connectivity state.

        Args:
            connected: True if network is connected, False otherwise.

        Emits:
            network_status_changed: With (connected) argument when state changes.
        """
        if self._network_connected != connected:
            self._network_connected = connected
            self.network_status_changed.emit(connected)

    # =========================================================================
    # NETWORK MOCK (for testing)
    # =========================================================================

    @property
    def has_network_override(self) -> bool:
        """Check if network state override is active."""
        return self._network_override is not None

    @property
    def network_override_value(self) -> Optional[bool]:
        """Get the current network override value (None if not overridden)."""
        return self._network_override

    def set_network_override(self, connected: bool) -> None:
        """
        Override network connectivity state for testing.

        When set, the actual network check is bypassed and this value
        is used instead. Call clear_network_override() to restore
        normal behavior.

        Args:
            connected: The mock connectivity state (False = simulate offline).

        Example:
            # Simulate offline mode for testing
            state = AppState.instance()
            state.set_network_override(False)

            # ... test offline behavior ...

            state.clear_network_override()  # Restore normal behavior
        """
        self._network_override = connected
        self.set_network_connected(connected)

    def clear_network_override(self) -> None:
        """
        Clear network override and restore normal connectivity checking.

        After calling this, network state will be determined by actual
        connectivity checks again.
        """
        self._network_override = None
active_software property

Get the name of the currently active software module.

has_network_override property

Check if network state override is active.

is_library_edit_mode property

Check if the library system is in edit view.

is_library_in_project_usage property

Check if the library system is being used within a project.

is_network_connected property

Check if the network is currently connected.

is_software_active property

Check if any software module is currently active.

network_override_value property

Get the current network override value (None if not overridden).

__init__()

Initialize the application state.

Source code in src\shared_services\state\app_state.py
def __init__(self) -> None:
    """Initialize the application state."""
    super().__init__()
    self._active_software: str = ""
    self._software_active: bool = False
    self._library_edit_mode: bool = False
    self._library_in_project_usage: bool = False
    self._network_connected: bool = True
    self._network_override: Optional[bool] = None
clear_active_software()

Clear the active software module.

Source code in src\shared_services\state\app_state.py
def clear_active_software(self) -> None:
    """Clear the active software module."""
    self.set_active_software("")
clear_network_override()

Clear network override and restore normal connectivity checking.

After calling this, network state will be determined by actual connectivity checks again.

Source code in src\shared_services\state\app_state.py
def clear_network_override(self) -> None:
    """
    Clear network override and restore normal connectivity checking.

    After calling this, network state will be determined by actual
    connectivity checks again.
    """
    self._network_override = None
instance() classmethod

Get the singleton instance.

Returns:

Type Description
AppState

The shared AppState instance.

Source code in src\shared_services\state\app_state.py
@classmethod
def instance(cls) -> "AppState":
    """
    Get the singleton instance.

    Returns:
        The shared AppState instance.
    """
    if cls._instance is None:
        cls._instance = cls()
    return cls._instance
reset_instance() classmethod

Reset the singleton instance.

Useful for testing to ensure clean state between tests.

Source code in src\shared_services\state\app_state.py
@classmethod
def reset_instance(cls) -> None:
    """
    Reset the singleton instance.

    Useful for testing to ensure clean state between tests.
    """
    cls._instance = None
set_active_software(name)

Set the active software module.

Parameters:

Name Type Description Default
name str

Name of the software module (e.g., "PlantDesign"). Empty string clears the active software.

required
Emits

software_changed: With (name, is_active) arguments.

Source code in src\shared_services\state\app_state.py
def set_active_software(self, name: str) -> None:
    """
    Set the active software module.

    Args:
        name: Name of the software module (e.g., "PlantDesign").
              Empty string clears the active software.

    Emits:
        software_changed: With (name, is_active) arguments.
    """
    self._active_software = name
    self._software_active = bool(name)
    self.software_changed.emit(name, self._software_active)
set_library_edit_mode(in_edit_view)

Set the library editing mode state.

Parameters:

Name Type Description Default
in_edit_view bool

True if editing a library, False otherwise.

required
Emits

library_mode_changed: With (in_edit_view) argument when state changes.

Source code in src\shared_services\state\app_state.py
def set_library_edit_mode(self, in_edit_view: bool) -> None:
    """
    Set the library editing mode state.

    Args:
        in_edit_view: True if editing a library, False otherwise.

    Emits:
        library_mode_changed: With (in_edit_view) argument when state changes.
    """
    if self._library_edit_mode != in_edit_view:
        self._library_edit_mode = in_edit_view
        self.library_mode_changed.emit(in_edit_view)
set_library_in_project_usage(active)

Set whether the library system is in project usage mode.

Parameters:

Name Type Description Default
active bool

True if library is used within a project context.

required
Emits

library_project_usage_changed: With (active) argument when state changes.

Source code in src\shared_services\state\app_state.py
def set_library_in_project_usage(self, active: bool) -> None:
    """
    Set whether the library system is in project usage mode.

    Args:
        active: True if library is used within a project context.

    Emits:
        library_project_usage_changed: With (active) argument when state changes.
    """
    if self._library_in_project_usage != active:
        self._library_in_project_usage = active
        self.library_project_usage_changed.emit(active)
set_network_connected(connected)

Set the network connectivity state.

Parameters:

Name Type Description Default
connected bool

True if network is connected, False otherwise.

required
Emits

network_status_changed: With (connected) argument when state changes.

Source code in src\shared_services\state\app_state.py
def set_network_connected(self, connected: bool) -> None:
    """
    Set the network connectivity state.

    Args:
        connected: True if network is connected, False otherwise.

    Emits:
        network_status_changed: With (connected) argument when state changes.
    """
    if self._network_connected != connected:
        self._network_connected = connected
        self.network_status_changed.emit(connected)
set_network_override(connected)

Override network connectivity state for testing.

When set, the actual network check is bypassed and this value is used instead. Call clear_network_override() to restore normal behavior.

Parameters:

Name Type Description Default
connected bool

The mock connectivity state (False = simulate offline).

required
Example
Simulate offline mode for testing

state = AppState.instance() state.set_network_override(False)

... test offline behavior ...

state.clear_network_override() # Restore normal behavior

Source code in src\shared_services\state\app_state.py
def set_network_override(self, connected: bool) -> None:
    """
    Override network connectivity state for testing.

    When set, the actual network check is bypassed and this value
    is used instead. Call clear_network_override() to restore
    normal behavior.

    Args:
        connected: The mock connectivity state (False = simulate offline).

    Example:
        # Simulate offline mode for testing
        state = AppState.instance()
        state.set_network_override(False)

        # ... test offline behavior ...

        state.clear_network_override()  # Restore normal behavior
    """
    self._network_override = connected
    self.set_network_connected(connected)