Fix silo loading and add integration enhancements

Fix the exec() calls in Create module's Init.py and InitGui.py to pass
__file__ and __name__ in the globals dict. The silo workbench code uses
__file__ to resolve icon paths, but exec() without explicit globals
does not provide it, causing 'name __file__ is not defined' errors.

Also add three silo integration enhancements to InitGui.py:
- First-startup check: launches Silo_Settings dialog if API URL is not
  configured on first run
- File menu injection: WorkbenchManipulator inserts Silo Open, Save,
  and Commit commands into the File menu across all workbenches
- Database activity panel: dock widget showing recent silo items,
  displayed on the right side of the main window
This commit is contained in:
forbes
2026-01-29 20:57:39 -06:00
parent 092a8a6d8b
commit dbac82e731
2 changed files with 102 additions and 2 deletions

View File

@@ -31,7 +31,10 @@ def setup_kindred_addons():
if os.path.isfile(init_file):
try:
with open(init_file) as f:
exec(compile(f.read(), init_file, "exec"))
exec_globals = globals().copy()
exec_globals["__file__"] = init_file
exec_globals["__name__"] = name
exec(compile(f.read(), init_file, "exec"), exec_globals)
FreeCAD.Console.PrintLog(f"Create: Loaded {name} Init.py\n")
except Exception as e:
FreeCAD.Console.PrintWarning(

View File

@@ -30,7 +30,13 @@ def setup_kindred_workbenches():
if os.path.isfile(init_gui_file):
try:
with open(init_gui_file) as f:
exec(compile(f.read(), init_gui_file, "exec"))
exec_globals = globals().copy()
exec_globals["__file__"] = init_gui_file
exec_globals["__name__"] = name
exec(
compile(f.read(), init_gui_file, "exec"),
exec_globals,
)
FreeCAD.Console.PrintLog(f"Create: Loaded {name} workbench\n")
except Exception as e:
FreeCAD.Console.PrintWarning(
@@ -40,3 +46,94 @@ def setup_kindred_workbenches():
setup_kindred_workbenches()
FreeCAD.Console.PrintLog("Create GUI module initialized\n")
# ---------------------------------------------------------------------------
# Silo integration enhancements
# ---------------------------------------------------------------------------
def _check_silo_first_start():
"""Show Silo settings dialog on first startup if not yet configured."""
try:
param = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/KindredSilo")
if not param.GetBool("FirstStartChecked", False):
param.SetBool("FirstStartChecked", True)
if not param.GetString("ApiUrl", ""):
FreeCADGui.runCommand("Silo_Settings")
except Exception as e:
FreeCAD.Console.PrintLog(f"Create: Silo first-start check skipped: {e}\n")
def _setup_silo_menu():
"""Inject Silo commands into the File menu across all workbenches."""
try:
class SiloMenuManipulator:
def modifyMenuBar(self):
return [
{"insert": "Silo_Open", "menuItem": "Std_Open", "after": ""},
{"insert": "Silo_Save", "menuItem": "Std_Save", "after": ""},
{"insert": "Silo_Commit", "menuItem": "Std_Save", "after": ""},
]
FreeCADGui.addWorkbenchManipulator(SiloMenuManipulator())
FreeCAD.Console.PrintLog("Create: Silo menu manipulator installed\n")
except Exception as e:
FreeCAD.Console.PrintLog(f"Create: Silo menu setup skipped: {e}\n")
def _setup_silo_activity_panel():
"""Show a dock widget with recent Silo database activity."""
try:
from PySide import QtCore, QtWidgets
mw = FreeCADGui.getMainWindow()
if mw is None:
return
# Don't create duplicate panels
if mw.findChild(QtWidgets.QDockWidget, "SiloDatabaseActivity"):
return
panel = QtWidgets.QDockWidget("Database Activity", mw)
panel.setObjectName("SiloDatabaseActivity")
widget = QtWidgets.QWidget()
layout = QtWidgets.QVBoxLayout(widget)
activity_list = QtWidgets.QListWidget()
layout.addWidget(activity_list)
try:
import silo_commands
items = silo_commands._client.list_items()
if isinstance(items, list):
for item in items[:20]:
pn = item.get("part_number", "")
desc = item.get("description", "")
updated = item.get("updated_at", "")
if updated:
updated = updated[:10]
activity_list.addItem(f"{pn} - {desc} - {updated}")
if activity_list.count() == 0:
activity_list.addItem("(No items in database)")
except Exception:
activity_list.addItem("(Unable to connect to Silo database)")
panel.setWidget(widget)
mw.addDockWidget(QtCore.Qt.RightDockWidgetArea, panel)
except Exception as e:
FreeCAD.Console.PrintLog(f"Create: Silo activity panel skipped: {e}\n")
# Defer enhancements until the GUI event loop is running
try:
from PySide.QtCore import QTimer
QTimer.singleShot(2000, _setup_silo_menu)
QTimer.singleShot(3000, _check_silo_first_start)
QTimer.singleShot(4000, _setup_silo_activity_panel)
except Exception:
pass