"""Editing context and overlay registration wrappers. Routes through the ``kcsdk`` C++ module. The legacy ``FreeCADGui`` Python bindings are deprecated — kcsdk is required. """ import FreeCAD try: import kcsdk as _kcsdk except ImportError: _kcsdk = None def _require_kcsdk(): if _kcsdk is None: raise RuntimeError( "kcsdk module not available. " "The kindred_sdk requires the kcsdk C++ module (libKCSDK)." ) def register_context(context_id, label, color, toolbars, match, priority=50): """Register an editing context. Parameters ---------- context_id : str Unique identifier (e.g. ``"myaddon.edit"``). label : str Display label template. Supports ``{name}`` placeholder. color : str Hex color for the breadcrumb (e.g. ``"#f38ba8"``). toolbars : list[str] Toolbar names to show when this context is active. match : callable Zero-argument callable returning *True* when this context is active. priority : int, optional Higher values are checked first. Default 50. """ if not isinstance(context_id, str): raise TypeError(f"context_id must be str, got {type(context_id).__name__}") if not isinstance(toolbars, list): raise TypeError(f"toolbars must be list, got {type(toolbars).__name__}") if not callable(match): raise TypeError("match must be callable") _require_kcsdk() try: _kcsdk.register_context(context_id, label, color, toolbars, match, priority) except Exception as e: FreeCAD.Console.PrintWarning( f"kindred_sdk: Failed to register context '{context_id}': {e}\n" ) def unregister_context(context_id): """Remove a previously registered editing context.""" if not isinstance(context_id, str): raise TypeError(f"context_id must be str, got {type(context_id).__name__}") _require_kcsdk() try: _kcsdk.unregister_context(context_id) except Exception as e: FreeCAD.Console.PrintWarning( f"kindred_sdk: Failed to unregister context '{context_id}': {e}\n" ) def register_overlay(overlay_id, toolbars, match): """Register an editing overlay. Overlays add toolbars to whatever context is currently active when *match* returns True. Parameters ---------- overlay_id : str Unique overlay identifier. toolbars : list[str] Toolbar names to append. match : callable Zero-argument callable returning *True* when the overlay applies. """ if not isinstance(overlay_id, str): raise TypeError(f"overlay_id must be str, got {type(overlay_id).__name__}") if not isinstance(toolbars, list): raise TypeError(f"toolbars must be list, got {type(toolbars).__name__}") if not callable(match): raise TypeError("match must be callable") _require_kcsdk() try: _kcsdk.register_overlay(overlay_id, toolbars, match) except Exception as e: FreeCAD.Console.PrintWarning( f"kindred_sdk: Failed to register overlay '{overlay_id}': {e}\n" ) def unregister_overlay(overlay_id): """Remove a previously registered editing overlay.""" if not isinstance(overlay_id, str): raise TypeError(f"overlay_id must be str, got {type(overlay_id).__name__}") _require_kcsdk() try: _kcsdk.unregister_overlay(overlay_id) except Exception as e: FreeCAD.Console.PrintWarning( f"kindred_sdk: Failed to unregister overlay '{overlay_id}': {e}\n" ) def inject_commands(context_id, toolbar_name, commands): """Inject commands into a context's toolbar. Parameters ---------- context_id : str Target context identifier. toolbar_name : str Toolbar within that context. commands : list[str] Command names to add. """ if not isinstance(context_id, str): raise TypeError(f"context_id must be str, got {type(context_id).__name__}") if not isinstance(toolbar_name, str): raise TypeError(f"toolbar_name must be str, got {type(toolbar_name).__name__}") if not isinstance(commands, list): raise TypeError(f"commands must be list, got {type(commands).__name__}") _require_kcsdk() try: _kcsdk.inject_commands(context_id, toolbar_name, commands) except Exception as e: FreeCAD.Console.PrintWarning( f"kindred_sdk: Failed to inject commands into '{context_id}': {e}\n" ) def current_context(): """Return the current editing context as a dict. Keys: ``id``, ``label``, ``color``, ``toolbars``, ``breadcrumb``, ``breadcrumbColors``. Returns ``None`` if no context is active. """ _require_kcsdk() try: return _kcsdk.current_context() except Exception as e: FreeCAD.Console.PrintWarning( f"kindred_sdk: Failed to get current context: {e}\n" ) return None def refresh_context(): """Force re-resolution and update of the editing context.""" _require_kcsdk() try: _kcsdk.refresh() except Exception as e: FreeCAD.Console.PrintWarning(f"kindred_sdk: Failed to refresh context: {e}\n")