Make every live edit reach the device, and warn when it doesn't
In live mode the device is now written first and the document only takes what the device accepted. Every live_hooks failure records a reason, and warn_failure() shows it in a dialog and the status bar instead of failing silently. - Move, properties, OX page editor: rejected values are rolled back and listed - Add/remove link: no longer edits the DOM alone when an end can't be resolved - Add/delete component: report why the device refused - Tidy Layout: sends each new position to the device, reverts refusals, marks the document dirty, and pushes no undo step in live mode - User Manager: add (one Sox add carrying cred/perm/prov), edit and delete now go to the device - Binary Buf slots (e.g. User.cred) are sent as Buf bytes, not as Str text - Bump version to 0.0.0.136 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+31
-2
@@ -7,9 +7,11 @@ import tkinter as tk
|
||||
import tkinter.font as tkfont
|
||||
|
||||
import app_state
|
||||
import live_hooks
|
||||
import schema
|
||||
import undo
|
||||
from sax_dom import get_component_path, read_meta_property, update_meta_property
|
||||
from sax_dom import (get_component_path, read_meta_property, remove_prop, set_prop_value,
|
||||
update_meta_property)
|
||||
|
||||
|
||||
LINK_STUB = 8 # straight run leaving a slot before the wire is allowed to turn
|
||||
@@ -1303,7 +1305,8 @@ def tidy_layout():
|
||||
the first column and row clear the canvas edge by at least TIDY_MARGIN, and
|
||||
neighbours are left at least TIDY_GAP apart, widened where wires need lanes. A sheet
|
||||
too wide for meta's 0..255 range is laid out at a coarser multiple of the grid rather
|
||||
than being squashed against the limit. Returns (moved_count, clamped_count).
|
||||
than being squashed against the limit. Returns (moved_count, clamped_count); in live
|
||||
mode moved_count is None when the device refused every move, already reported.
|
||||
"""
|
||||
if not app_state.canvas_comp_map:
|
||||
return 0, 0
|
||||
@@ -1327,6 +1330,32 @@ def tidy_layout():
|
||||
|
||||
command = undo.MetaMoveCommand(changes, label="tidy layout")
|
||||
command.redo() # apply it; the command is the single writer of meta
|
||||
|
||||
if app_state.live_mode:
|
||||
# No undo in live mode: each new position goes to the device, and a box the
|
||||
# device refused goes back to where the device still has it.
|
||||
failures = []
|
||||
for element, old_val, _, _ in changes:
|
||||
new_val = element.find("prop[@name='meta']").get("val", "0")
|
||||
if not live_hooks.live_set_prop_value(element, "meta", new_val):
|
||||
failures.append(f"{element.get('name', '?')}: {live_hooks.last_error}")
|
||||
if old_val is None:
|
||||
remove_prop(element, "meta")
|
||||
else:
|
||||
set_prop_value(element, "meta", old_val)
|
||||
render_current_sheet()
|
||||
if failures:
|
||||
live_hooks.warn_failure(
|
||||
"Tidy Layout",
|
||||
f"{len(failures)} of {len(changes)} component(s) could not be moved on the "
|
||||
"device and were left where they were",
|
||||
"\n".join(f" • {failure}" for failure in failures),
|
||||
)
|
||||
if len(failures) == len(changes):
|
||||
return None, clamped # already reported; nothing moved
|
||||
app_state.mark_dirty()
|
||||
return len(changes) - len(failures), clamped
|
||||
|
||||
undo.push(command)
|
||||
app_state.mark_dirty()
|
||||
render_current_sheet()
|
||||
|
||||
Reference in New Issue
Block a user