pySimBlocks.gui.project_controller

class pySimBlocks.gui.project_controller.ProjectController(project_state: ProjectState, view: DiagramView, resolve_block_meta: Callable[[str, str], BlockMeta], undo_manager: UndoManager)[source]

Bases: QObject

Controller coordinating all mutations to the project model and diagram view.

Acts as the single point of truth for block and connection lifecycle operations, dirty-state tracking, plot management, and simulation parameter updates.

project_state

Shared mutable state of the open project.

view

The diagram canvas widget.

resolve_block_meta

Callable returning BlockMeta for a given category and block type.

is_dirty

True if there are unsaved changes.

dirty_changed: Signal

Signal emitted with the new dirty flag value whenever the unsaved-changes state changes.

add_block(category: str, block_type: str, block_layout: dict | None = None) BlockInstance[source]

Create and add a new block of the given type to the project.

Parameters:
  • category – Category name of the block.

  • block_type – Type name of the block within the category.

  • block_layout – Optional dict with position/size hints for the view.

Returns:

The newly created BlockInstance.

add_copy_block(block_instance: BlockInstance) BlockInstance[source]

Add a copy of an existing block to the project.

Parameters:

block_instance – The block to copy.

Returns:

The newly created copy as a BlockInstance.

copy_selection() bool[source]

Copy the current diagram selection to the view clipboard.

paste_clipboard_at(origin: QPointF) bool[source]

Paste the view clipboard at origin (undoable).

rename_block(block_instance: BlockInstance, new_name: str) None[source]

Rename a block and update all references in logging and plot signals.

Parameters:
  • block_instance – The block to rename.

  • new_name – Desired new name. A unique suffix is appended if the name is already taken.

update_block_param(block_instance: BlockInstance, params: dict[str, Any]) None[source]

Apply new parameter values to a block, refreshing ports and connections as needed.

Parameters:
  • block_instance – The block to update.

  • params – New parameter dict. If a 'name' key is present the block is also renamed.

remove_block(block_instance: BlockInstance) None[source]

Remove a block, its connections, and its signals from the project.

Parameters:

block_instance – The block to remove.

group_blocks(blocks: list[BlockInstance], name: str | None = None, *, child_group_uids: list[str] | None = None, parent_uid: str | None = None) VisualGroup | None[source]

Create a visual group from blocks and/or child groups (undoable).

ungroup(group_uid: str) bool[source]

Remove a visual group by UID (undoable).

delete_group(group_uid: str) bool[source]

Delete a visual group and all nested content (undoable).

group_selected_blocks() VisualGroup | None[source]

Group the current diagram selection of blocks and/or groups.

ungroup_selected_group() bool[source]

Ungroup the currently selected visual group.

add_block_to_group(group_uid: str, block_instance: BlockInstance, layout: dict[str, Any] | None = None) bool[source]

Add an existing block to a visual group (undoable).

add_block_in_group_view(category: str, block_type: str, group_uid: str) BlockInstance | None[source]

Drop a new palette block into a group’s internal view (undoable).

remove_block_from_group(group_uid: str, block_uid: str) bool[source]

Remove a block from a visual group without deleting it (undoable).

try_wire_boundary_endpoints(src, dst) bool[source]

Wire group boundaries, proxies, or group-to-group borders.

boundary_port_flow_label(group: VisualGroup, boundary: BoundaryPort) str[source]

Return the flow label for a boundary (source for In, destination for Out).

boundary_proxy_label(boundary: BoundaryPort) str[source]

Return the label drawn on a GroupIn/GroupOut proxy.

rename_boundary_port(group_uid: str, boundary_uid: str, new_label: str) bool[source]

Rename one proxy label (empty string resets automatic label).

rename_visual_group(group_uid: str, new_name: str) bool[source]

Rename a visual group (undoable).

make_unique_name(base_name: str) str[source]

Return base_name or a suffixed variant that is unique across all blocks.

Parameters:

base_name – Desired block name.

Returns:

base_name if available, otherwise base_name_N for the smallest N that is not already taken.

is_name_available(name: str, current=None) bool[source]

Return True if name is not already used by another block.

Parameters:
  • name – Name to check for availability.

  • current – Block instance to exclude from the check (e.g. the block being renamed).

Returns:

True if the name is free, False if it is taken by another block.

try_connect_boundary_ports(port1: PortInstance, port2: PortInstance) bool[source]

Complete or wire a manual group boundary instead of a direct connection.

add_connection(port1: PortInstance, port2: PortInstance, points: list[QPointF] | None = None) None[source]

Create a connection between two ports if compatible.

The method silently returns without creating a connection if the ports are not compatible or if the destination port cannot accept another connection.

Parameters:
  • port1 – First port (output or input).

  • port2 – Second port (input or output).

  • points – Optional list of intermediate waypoints for the wire.

remove_connection(connection: ConnectionInstance) None[source]

Remove a connection from both the model and the view.

Parameters:

connection – The ConnectionInstance to remove.

execute_move_resize_block(block_instance: BlockInstance, old_pos: QPointF, old_rect: QRectF, new_pos: QPointF, new_rect: QRectF) None[source]
execute_move_resize_group(group_uid: str, old_pos: QPointF, old_rect: QRectF, new_pos: QPointF, new_rect: QRectF) None[source]
execute_toggle_orientation(block_instance: BlockInstance) None[source]
execute_toggle_group_orientation(group_uid: str) None[source]
execute_toggle_proxy_orientation(group_uid: str, boundary_uid: str) None[source]
execute_edit_connection_route(connection: ConnectionInstance, old_points: list[QPointF] | None, new_points: list[QPointF] | None) None[source]
execute_move_proxy_layout(group_uid: str, boundary_uid: str, old_pos: QPointF, new_pos: QPointF) None[source]
begin_macro(text: str) None[source]
end_macro() None[source]
make_dirty() None[source]

Mark the project as having unsaved changes and emit dirty_changed.

mark_gui_layout_dirty() None[source]

Mark GUI-only layout edits that stay outside the undo/redo stack.

clear_dirty() None[source]

Clear the unsaved-changes flag and emit dirty_changed.

clear() None[source]

Reset the project state and diagram view to an empty state.

update_project_param(new_path: Path, ext: str) None[source]

Update the project directory path and external module reference.

Parameters:
  • new_path – New project directory path.

  • ext – New external module path string, or '' to clear it.

load_project(loader: ProjectLoader) None[source]

Delegate project loading to the given loader service.

Parameters:

loader – A ProjectLoader implementation that reads the project files and populates this controller.

create_plot(title: str, signals: list[str], mode: str = 'auto') None[source]

Append a new plot to the project configuration.

Parameters:
  • title – Title of the plot figure.

  • signals – List of signal names to display in the plot. Any signal not already logged is automatically added to the logging list.

  • mode – Plot display mode (auto, overlay, split_signals, or split_components).

update_plot(index: int, title: str, signals: list[str], mode: str = 'auto', series_styles: dict[str, dict[str, str]] | None = None) None[source]

Update the title and signals of an existing plot.

Parameters:
  • index – Index of the plot in ProjectState.plots.

  • title – New title for the plot.

  • signals – New list of signal names. Any signal not yet logged is automatically added.

  • mode – Plot display mode (auto, overlay, split_signals, or split_components).

  • series_styles – Optional per-component style map for YAML storage.

delete_plot(index: int) None[source]

Remove a plot by index.

Parameters:

index – Index of the plot in ProjectState.plots.

add_manual_layout_preset(plot: dict) int[source]

Append a manual multi-panel layout preset to the project.

Parameters:

plot – Plot descriptor with layout: manual and panels.

Returns:

Index of the new preset in ProjectState.plots.

update_manual_layout_preset(index: int, plot: dict) None[source]

Replace an existing manual layout preset at index.

Parameters:
  • index – Index in ProjectState.plots.

  • plot – Plot descriptor with layout: manual and panels.

update_simulation_params(params: dict[str, float | str]) None[source]

Apply new simulation parameters to the project state.

Parameters:

params – Dict of simulation parameters (e.g. dt, T).

set_logged_signals(signals: list[str]) None[source]

Replace the logging list with signals, preserving insertion order.

Parameters:

signals – New list of signal names to log. Duplicates are removed while preserving the first occurrence.

apply_member_layouts(group: VisualGroup) None[source]

Apply stored member layouts to visible block items.

save_member_layouts(group: VisualGroup) None[source]

Persist current block item geometry into the group model.

restore_members_after_ungroup(group: VisualGroup) None[source]

Place ungrouped members and promote child groups to the parent level.

ensure_group_boundary_proxies(group: VisualGroup) None[source]

Assign proxy ids and default layouts for each group boundary port.

save_proxy_layouts(group: VisualGroup) None[source]

Persist current proxy item positions into the group model.

add_manual_boundary_port(group_uid: str, direction: str, pos: QPointF) BoundaryPort | None[source]

Add a manual GroupIn/GroupOut boundary port to a visual group.

remove_boundary_port(group_uid: str, boundary_uid: str) bool[source]

Remove a GroupIn/GroupOut boundary port (undoable).

disconnect_manual_boundary_side(group_uid: str, boundary_uid: str, side: str) bool[source]

Disconnect one side of an incomplete manual boundary wire (undoable).

remove_manual_boundary_port(group_uid: str, boundary_uid: str) bool[source]

Remove a manual GroupIn/GroupOut boundary port (undoable).

staticMetaObject = PySide6.QtCore.QMetaObject("ProjectController" inherits "QObject": Methods:   #4 type=Signal, signature=dirty_changed(bool), parameters=bool )