Reorganized the application around a clear frontend/backend boundary.
src/bedit/
├── __main__.py
├── core/ # Pure Python, no PySide
│ ├── model.py
│ ├── port_types.py
│ ├── serializer.py
│ └── libraries.py
└── gui/ # All Qt-dependent code
├── app.py
├── main_window.py
├── preferences.py
├── controllers/
├── dialogs/
├── graphics/
├── models/
└── generated/ # Designer/resource output only
Notable improvements:
Domain models, serialization, port types, and library parsing are now Qt-free.
Qt signals and undo infrastructure are explicitly isolated under gui/controllers.
Library parsing is separated from the Qt repository and tree models.
All generated Python is contained in gui/generated.
Designer build tasks now write to the generated directory.
The application entry point and package metadata use the new paths.
README now documents the structure and dependency rules.
Removed the old mixed document, library, and workspace packages.
This commit is contained in:
262
BEdit/src/bedit/gui/controllers/commands.py
Normal file
262
BEdit/src/bedit/gui/controllers/commands.py
Normal file
@@ -0,0 +1,262 @@
|
||||
from PySide6.QtCore import QPointF
|
||||
from PySide6.QtGui import QUndoCommand
|
||||
|
||||
from bedit.core.model import Component, Connection, Port
|
||||
|
||||
|
||||
class AddComponentCommand(QUndoCommand):
|
||||
def __init__(self, controller, owner_id: str | None, component: Component) -> None:
|
||||
super().__init__(f"Add {component.name}")
|
||||
self.controller = controller
|
||||
self.owner_id = owner_id
|
||||
self.component = component
|
||||
|
||||
def redo(self) -> None:
|
||||
self.controller._insert_component(self.owner_id, self.component)
|
||||
|
||||
def undo(self) -> None:
|
||||
self.controller._remove_component(self.owner_id, self.component.id)
|
||||
|
||||
|
||||
class MoveComponentCommand(QUndoCommand):
|
||||
def __init__(
|
||||
self,
|
||||
controller,
|
||||
owner_id: str,
|
||||
component_id: str,
|
||||
old: QPointF,
|
||||
new: QPointF,
|
||||
) -> None:
|
||||
super().__init__("Move component")
|
||||
self.controller = controller
|
||||
self.owner_id = owner_id
|
||||
self.component_id = component_id
|
||||
self.old = old
|
||||
self.new = new
|
||||
|
||||
def redo(self) -> None:
|
||||
self.controller._move_component(self.owner_id, self.component_id, self.new)
|
||||
|
||||
def undo(self) -> None:
|
||||
self.controller._move_component(self.owner_id, self.component_id, self.old)
|
||||
|
||||
|
||||
class RotateComponentsCommand(QUndoCommand):
|
||||
def __init__(
|
||||
self,
|
||||
controller,
|
||||
owner_id: str,
|
||||
rotations: dict[str, tuple[float, float]],
|
||||
) -> None:
|
||||
super().__init__("Rotate components")
|
||||
self.controller = controller
|
||||
self.owner_id = owner_id
|
||||
self.rotations = rotations
|
||||
|
||||
def redo(self) -> None:
|
||||
for component_id, (_old, new) in self.rotations.items():
|
||||
self.controller._rotate_component(self.owner_id, component_id, new)
|
||||
|
||||
def undo(self) -> None:
|
||||
for component_id, (old, _new) in self.rotations.items():
|
||||
self.controller._rotate_component(self.owner_id, component_id, old)
|
||||
|
||||
|
||||
class AddConnectionCommand(QUndoCommand):
|
||||
def __init__(self, controller, owner_id: str, connection: Connection) -> None:
|
||||
super().__init__("Connect components")
|
||||
self.controller = controller
|
||||
self.owner_id = owner_id
|
||||
self.connection = connection
|
||||
|
||||
def redo(self) -> None:
|
||||
self.controller._insert_connection(self.owner_id, self.connection)
|
||||
|
||||
def undo(self) -> None:
|
||||
self.controller._remove_connection(self.owner_id, self.connection.id)
|
||||
|
||||
|
||||
class ReplaceComponentCommand(QUndoCommand):
|
||||
def __init__(self, controller, old: Component, new: Component) -> None:
|
||||
super().__init__("Apply JSON changes")
|
||||
self.controller = controller
|
||||
self.old = old
|
||||
self.new = new
|
||||
|
||||
def redo(self) -> None:
|
||||
self.controller._replace_component(self.old.id, self.new)
|
||||
|
||||
def undo(self) -> None:
|
||||
self.controller._replace_component(self.new.id, self.old)
|
||||
|
||||
|
||||
class AddInterfacePortCommand(QUndoCommand):
|
||||
def __init__(self, controller, owner_id: str, direction: str, port: Port) -> None:
|
||||
super().__init__(f"Add {direction}")
|
||||
self.controller = controller
|
||||
self.owner_id = owner_id
|
||||
self.direction = direction
|
||||
self.port = port
|
||||
|
||||
def redo(self) -> None:
|
||||
self.controller._insert_interface_port(self.owner_id, self.direction, self.port)
|
||||
|
||||
def undo(self) -> None:
|
||||
self.controller._remove_interface_port(self.owner_id, self.direction, self.port.id)
|
||||
|
||||
|
||||
class ReplaceSourceCommand(QUndoCommand):
|
||||
def __init__(self, controller, component_id: str, old: dict, new: dict) -> None:
|
||||
super().__init__("Apply source JSON")
|
||||
self.controller = controller
|
||||
self.component_id = component_id
|
||||
self.old = old
|
||||
self.new = new
|
||||
|
||||
def redo(self) -> None:
|
||||
self.controller._replace_source(self.component_id, self.new)
|
||||
|
||||
def undo(self) -> None:
|
||||
self.controller._replace_source(self.component_id, self.old)
|
||||
|
||||
|
||||
class MoveInterfacePortCommand(QUndoCommand):
|
||||
def __init__(self, controller, owner_id: str, port_id: str, old: QPointF, new: QPointF) -> None:
|
||||
super().__init__("Move interface terminal")
|
||||
self.controller = controller
|
||||
self.owner_id = owner_id
|
||||
self.port_id = port_id
|
||||
self.old = old
|
||||
self.new = new
|
||||
|
||||
def redo(self) -> None:
|
||||
self.controller._move_interface_port(self.owner_id, self.port_id, self.new)
|
||||
|
||||
def undo(self) -> None:
|
||||
self.controller._move_interface_port(self.owner_id, self.port_id, self.old)
|
||||
|
||||
|
||||
class EditComponentAppearanceCommand(QUndoCommand):
|
||||
def __init__(self, controller, component_id: str, old: dict, new: dict) -> None:
|
||||
super().__init__("Edit component appearance")
|
||||
self.controller = controller
|
||||
self.component_id = component_id
|
||||
self.old = old
|
||||
self.new = new
|
||||
|
||||
def redo(self) -> None:
|
||||
self.controller._set_component_appearance(self.component_id, self.new)
|
||||
|
||||
def undo(self) -> None:
|
||||
self.controller._set_component_appearance(self.component_id, self.old)
|
||||
|
||||
|
||||
class RenameInterfacePortCommand(QUndoCommand):
|
||||
def __init__(self, controller, owner_id: str, port_id: str, old: str, new: str) -> None:
|
||||
super().__init__("Rename interface port")
|
||||
self.controller, self.owner_id, self.port_id = controller, owner_id, port_id
|
||||
self.old, self.new = old, new
|
||||
|
||||
def redo(self) -> None:
|
||||
self.controller._rename_interface_port(self.owner_id, self.port_id, self.new)
|
||||
|
||||
def undo(self) -> None:
|
||||
self.controller._rename_interface_port(self.owner_id, self.port_id, self.old)
|
||||
|
||||
|
||||
class RenameConnectionCommand(QUndoCommand):
|
||||
def __init__(self, controller, owner_id: str, connection_id: str, old: str, new: str) -> None:
|
||||
super().__init__("Rename connection")
|
||||
self.controller, self.owner_id, self.connection_id = controller, owner_id, connection_id
|
||||
self.old, self.new = old, new
|
||||
|
||||
def redo(self) -> None:
|
||||
self.controller._rename_connection(self.owner_id, self.connection_id, self.new)
|
||||
|
||||
def undo(self) -> None:
|
||||
self.controller._rename_connection(self.owner_id, self.connection_id, self.old)
|
||||
|
||||
|
||||
class DeleteSelectionCommand(QUndoCommand):
|
||||
def __init__(
|
||||
self,
|
||||
controller,
|
||||
owner_id: str | None,
|
||||
blocks: dict[str, Component],
|
||||
connections: dict[str, Connection],
|
||||
inputs: list[Port],
|
||||
outputs: list[Port],
|
||||
) -> None:
|
||||
super().__init__("Delete selection")
|
||||
self.controller = controller
|
||||
self.owner_id = owner_id
|
||||
self.blocks = blocks
|
||||
self.connections = connections
|
||||
self.inputs = inputs
|
||||
self.outputs = outputs
|
||||
|
||||
def redo(self) -> None:
|
||||
self.controller._delete_items(
|
||||
self.owner_id,
|
||||
set(self.blocks),
|
||||
set(self.connections),
|
||||
{port.id for port in self.inputs},
|
||||
{port.id for port in self.outputs},
|
||||
)
|
||||
|
||||
def undo(self) -> None:
|
||||
self.controller._restore_items(
|
||||
self.owner_id,
|
||||
self.blocks,
|
||||
self.connections,
|
||||
self.inputs,
|
||||
self.outputs,
|
||||
)
|
||||
|
||||
|
||||
class PasteSelectionCommand(QUndoCommand):
|
||||
def __init__(
|
||||
self,
|
||||
controller,
|
||||
owner_id: str,
|
||||
blocks: dict[str, Component],
|
||||
connections: dict[str, Connection],
|
||||
) -> None:
|
||||
super().__init__("Paste selection")
|
||||
self.controller = controller
|
||||
self.owner_id = owner_id
|
||||
self.blocks = blocks
|
||||
self.connections = connections
|
||||
|
||||
def redo(self) -> None:
|
||||
self.controller._restore_items(
|
||||
self.owner_id,
|
||||
self.blocks,
|
||||
self.connections,
|
||||
[],
|
||||
[],
|
||||
)
|
||||
|
||||
def undo(self) -> None:
|
||||
self.controller._delete_items(
|
||||
self.owner_id,
|
||||
set(self.blocks),
|
||||
set(self.connections),
|
||||
set(),
|
||||
set(),
|
||||
)
|
||||
|
||||
|
||||
class EditTextDefinitionCommand(QUndoCommand):
|
||||
def __init__(self, controller, component_id: str, old: dict, new: dict) -> None:
|
||||
super().__init__("Edit text component")
|
||||
self.controller = controller
|
||||
self.component_id = component_id
|
||||
self.old = old
|
||||
self.new = new
|
||||
|
||||
def redo(self) -> None:
|
||||
self.controller._set_text_definition(self.component_id, self.new)
|
||||
|
||||
def undo(self) -> None:
|
||||
self.controller._set_text_definition(self.component_id, self.old)
|
||||
Reference in New Issue
Block a user