Files
create/src/Mod/Create/silo_objects.py
forbes e947822c7a
All checks were successful
Build and Test / build (pull_request) Successful in 30m48s
feat(create): metadata editor — editable form with dirty tracking and save-back (#39)
Add SiloMetadataEditor widget that opens in an MDI subwindow when the
user double-clicks the Metadata node in the Silo tree. Supports editing
lifecycle state, tags (add/remove chips), and schema-defined fields with
type-inferred widgets (QCheckBox, QDoubleSpinBox, QLineEdit).

Changes:
- silo_viewers.py: SiloMetadataEditor with dirty tracking, Save/Reset
  buttons, unsaved-changes close guard, and tag chip management
- silo_objects.py: mark_dirty()/is_dirty()/clear_dirty() on proxy
- kc_format.py: fix entries=None before hooks; _metadata_save_hook
  writes dirty RawContent back to silo/ cache on document save

Closes #39
2026-02-18 17:11:05 -06:00

71 lines
1.9 KiB
Python

"""
silo_objects.py - Create FeaturePython proxy for Silo tree leaf nodes.
Each silo/ ZIP entry in a .kc file gets one SiloViewerObject in the
FreeCAD document tree. All properties are Transient so they are never
persisted in Document.xml.
"""
import FreeCAD
class SiloViewerObject:
"""Proxy for App::FeaturePython silo viewer nodes.
Properties (all Transient):
SiloPath - ZIP entry path, e.g. "silo/manifest.json"
ContentType - "json", "yaml", or "py"
RawContent - decoded UTF-8 content of the entry
"""
def __init__(self, obj):
obj.Proxy = self
obj.addProperty(
"App::PropertyString",
"SiloPath",
"Silo",
"ZIP entry path of this silo item",
)
obj.addProperty(
"App::PropertyString",
"ContentType",
"Silo",
"Content type of this silo item",
)
obj.addProperty(
"App::PropertyString",
"RawContent",
"Silo",
"Raw text content of this silo entry",
)
obj.setPropertyStatus("SiloPath", "Transient")
obj.setPropertyStatus("ContentType", "Transient")
obj.setPropertyStatus("RawContent", "Transient")
obj.setEditorMode("SiloPath", 1) # read-only in property panel
obj.setEditorMode("ContentType", 1)
obj.setEditorMode("RawContent", 2) # hidden in property panel
def execute(self, obj):
pass
def mark_dirty(self):
"""Flag this object's content as modified by a viewer widget."""
self._dirty = True
def is_dirty(self):
"""Return True if content has been modified since last save."""
return getattr(self, "_dirty", False)
def clear_dirty(self):
"""Clear the dirty flag after saving."""
self._dirty = False
def __getstate__(self):
return None
def __setstate__(self, state):
pass