""" SaveUtils FreeCAD Addon - InitGui.py FreeCAD runs Init.py/InitGui.py with `globals` and `locals` as two different dicts. Top-level statements bind into locals, but functions defined here capture globals as their `__globals__` — so *nothing* bound at the top of this file is visible from inside a function here. Names FreeCAD already put in `__main__` (FreeCAD, FreeCADGui) do resolve, which makes the trap easy to miss. Consequence: every function below must import what it needs locally, and the real work lives in SaveUtils.py where module globals behave normally. """ import FreeCAD import FreeCADGui FreeCAD.Console.PrintLog("=== SaveUtils: InitGui.py loading ===\n") class SaveUtilsWorkbench(FreeCADGui.Workbench): MenuText = "SaveUtils" ToolTip = "Save utility commands" def Initialize(self): pass def Activated(self): pass def Deactivated(self): pass FreeCADGui.addWorkbench(SaveUtilsWorkbench()) def _on_workbench_activated(name): # Local imports only — see the module docstring. import FreeCAD from PySide import QtCore # NoneWorkbench fires before the UI is ready — skip it if name == "NoneWorkbench": return try: import SaveUtils # FreeCAD rebuilds the menu bar around this signal, so right now some of # the QMenus it hands out are Python wrappers whose C++ half has already # been destroyed. Let the event loop come back round before touching # them. install_safely() is idempotent, so running it again on later # workbench switches is harmless and re-adds the items if a rebuild # dropped them. QtCore.QTimer.singleShot(0, SaveUtils.install_safely) except Exception as exc: FreeCAD.Console.PrintError(f"=== SaveUtils install error: {exc} ===\n") FreeCADGui.getMainWindow().workbenchActivated.connect(_on_workbench_activated)