""" silo_viewproviders.py - ViewProvider proxy for Silo tree leaf nodes. Controls tree icon, double-click behavior, and context menu for SiloViewerObject nodes in the document tree. """ import os # Icon directory — Phase 6 will add SVGs here. _ICON_DIR = os.path.join( os.path.dirname(os.path.abspath(__file__)), "resources", "icons", ) # Map silo/ paths to icon basenames (without .svg extension). _SILO_PATH_ICONS = { "silo/manifest.json": "silo-manifest", "silo/metadata.json": "silo-metadata", "silo/history.json": "silo-history", "silo/approvals.json": "silo-approvals", "silo/dependencies.json": "silo-dependencies", } # Prefix-based fallbacks for subdirectory entries. _SILO_PREFIX_ICONS = { "silo/jobs/": "silo-job", "silo/macros/": "silo-macro", } def _icon_for_path(silo_path): """Return absolute icon path for a silo/ entry, or '' if not found.""" name = _SILO_PATH_ICONS.get(silo_path) if name is None: for prefix, icon_name in _SILO_PREFIX_ICONS.items(): if silo_path.startswith(prefix): name = icon_name break if name is None: return "" path = os.path.join(_ICON_DIR, f"{name}.svg") return path if os.path.exists(path) else "" class SiloViewerViewProvider: """ViewProvider proxy for SiloViewerObject leaf nodes.""" def __init__(self, vobj): vobj.Proxy = self self.Object = vobj.Object def attach(self, vobj): """Store back-reference; called on document restore.""" self.Object = vobj.Object def getIcon(self): """Return icon path based on SiloPath; '' uses FreeCAD default.""" try: return _icon_for_path(self.Object.SiloPath) except Exception: return "" def doubleClicked(self, vobj): """Open a read-only MDI viewer for this silo node.""" try: import FreeCADGui from PySide import QtWidgets from silo_viewers import create_viewer_widget obj = vobj.Object widget = create_viewer_widget(obj) if widget is None: return False mw = FreeCADGui.getMainWindow() mdi = mw.findChild(QtWidgets.QMdiArea) if mdi is None: return False # Reuse existing subwindow if already open for this object target_name = widget.objectName() for sw in mdi.subWindowList(): if sw.widget() and sw.widget().objectName() == target_name: widget.deleteLater() mdi.setActiveSubWindow(sw) sw.show() return True sw = mdi.addSubWindow(widget) sw.setWindowTitle(getattr(widget, "WINDOW_TITLE", "Silo Viewer")) sw.show() mdi.setActiveSubWindow(sw) return True except Exception as exc: import FreeCAD FreeCAD.Console.PrintWarning( f"silo_viewproviders: doubleClicked failed: {exc}\n" ) return False def setupContextMenu(self, vobj, menu): """Phase 1: no context menu items.""" pass def __getstate__(self): return None def __setstate__(self, state): pass