Improve User Manager: Workbench-style permissions dialog, live mode support, double-click to open

- Permissions dialog now uses two-level UI: compact Edit User with >> buttons
  opening a separate grid dialog (Groups x Operator/Admin columns) with
  Clear All / Set All and auto-cascade (write implies read, admin implies operator)
- Provisioning has its own >> popup dialog
- Removed live mode restrictions for add/edit/delete user operations
- Broadened type detection and added safe int conversion for live mode values
- Double-click on tree node or canvas box opens special view (User Manager for
  UserService, Properties for other components)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-09-22 20:57:49 +03:00
co-authored by Claude Opus 4.6
parent 43549046e5
commit d5ef8eea6f
3 changed files with 264 additions and 76 deletions
+38
View File
@@ -985,6 +985,42 @@ def on_tree_right_click(event):
tree_comp_context_menu.post(event.x_root, event.y_root)
def _open_special_view(comp):
"""Opens the type-specific view for a component, or Properties as fallback."""
if user_service_view.is_user_service(comp):
show_user_service(comp)
return
show_properties(comp)
def on_tree_double_click(event):
"""Double-click on a tree node opens its special view (or Properties)."""
tree = app_state.tree
item_id = tree.identify_row(event.y)
if not item_id or tree.parent(item_id) == "":
return
comp = app_state.tree_element_map.get(item_id)
if comp is not None:
_open_special_view(comp)
def on_canvas_double_click(event):
"""Double-click on a canvas component opens its special view (or Properties)."""
canvas = app_state.canvas
cx = canvas.canvasx(event.x)
cy = canvas.canvasy(event.y)
clicked = canvas.find_closest(cx, cy, halo=3)
if not clicked:
return
tags = canvas.gettags(clicked[0])
group_tag = next((t for t in tags if t.startswith("comp_group_")), None)
if group_tag is None:
return
comp = app_state.canvas_comp_map.get(group_tag)
if comp is not None:
_open_special_view(comp)
def on_canvas_click(event):
canvas = app_state.canvas
canvas.itemconfig("block_outline", outline="#7f9db9", width=2)
@@ -2502,6 +2538,7 @@ tree.bind("<<TreeviewSelect>>", on_tree_select)
tree.bind("<ButtonPress-3>", on_tree_right_click)
tree.bind("<ButtonPress-2>", on_tree_right_click)
tree.bind("<Double-1>", on_tree_double_click)
left_pane.add(frame_tree, weight=3)
@@ -2729,6 +2766,7 @@ canvas.bind("<Configure>", lambda e: wiresheet.draw_grid())
canvas.bind("<ButtonPress-3>", on_canvas_right_click)
canvas.bind("<ButtonPress-2>", on_canvas_right_click)
canvas.bind("<Double-1>", on_canvas_double_click)
# Wheel zoom. Windows and macOS report a delta; X11 sends button 4 and 5 instead.
canvas.bind("<Control-MouseWheel>", on_canvas_wheel_zoom)