- Add Spreadsheet color preferences to KindredCreate.cfg using FCText
entries (TextColor, AliasedCellBackgroundColor, PositiveNumberColor,
NegativeNumberColor) matching the C++ GetASCII() reader in SheetModel.cpp
- Remove CatppuccinMocha install directive from CMakeLists.txt
- Update ztools submodule: theme.py deleted, CatppuccinMocha preference
pack removed, package.xml cleaned up
The previous apply_spreadsheet_colors() in ztools was a no-op: it called
SetUnsigned() but the Spreadsheet C++ reads GetASCII() — different param
types in FreeCAD's parameter system. Now properly fixed via preference pack.
Closes#278
Wire live data fetching, SSE subscriptions, and server write-back into
the History, Metadata, and Dependency viewer widgets.
Changes:
- Add server integration helpers (_init_server, _is_online,
_get_part_number, offline banner) with lazy silo_commands import
- SiloHistoryViewer: Refresh button fetches live revisions via
SiloClient.get_revisions(); SSE revision_created auto-refreshes
- SiloMetadataEditor: Save pushes to server (update_metadata,
patch_lifecycle, patch_tags); SSE item_updated refreshes form
when no local edits pending; offline banner
- SiloDependencyTable: Server-side UUID resolution via
resolve_dependencies(); Download button for unresolved items;
Refresh re-checks status; three-state icons (resolved/
downloadable/missing)
- All viewers show 'Offline — showing cached data' banner when
disconnected and disable server-dependent controls
Bump silo submodule to track new silo-client API methods:
get_metadata, update_metadata, patch_lifecycle, patch_tags,
resolve_dependencies (silo-client PR #19)
Closeskindred/silo-mod#43
Add 10 SVG placeholder icons copied from existing silo action icons.
These provide immediate visual feedback in the document tree while
proper Catppuccin-themed icons are designed later.
Icons: silo-group, silo-manifest, silo-metadata, silo-history,
silo-approvals, silo-dependencies, silo-job, silo-macro,
silo-jobs-group, silo-macros-group
Also adds install(DIRECTORY) rule for resources/icons/ in CMakeLists.
Closes#42
Add four viewer widgets for the remaining Silo tree node types:
- SiloApprovalsViewer: ECO approval status cards with colored status
icons, state badge, and Open in Silo Web UI button
- SiloDependencyTable: QTableView with resolution status (checks open
documents for matching part_uuid)
- SiloJobViewer: YAML source editor with Edit/Lock toggle, monospace
font, dirty tracking, and unsaved-changes guard
- SiloMacroEditor: Python source editor with Run Now (exec in FreeCAD
context), Save button, and dirty tracking
Also extends the viewer factory with prefix-based routing for
silo/jobs/*.yaml and silo/macros/*.py entries.
Closes#41
Add SiloHistoryViewer widget that opens in an MDI subwindow when the
user double-clicks the History node in the Silo tree. Displays revision
cards newest-first with revision number, Catppuccin-themed lifecycle
status badges, author, timestamp, and commit comment.
Changes:
- silo_viewers.py: SiloHistoryViewer with revision card layout,
status badge QSS, scroll area, empty-history placeholder
Closes#40
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
Add SiloManifestViewer widget that opens in an MDI subwindow when the
user double-clicks the Manifest node in the Silo tree. Displays all
manifest.json fields in a read-only QFormLayout with copy buttons for
Part UUID and Silo Instance.
New files:
- silo_viewers.py: SiloManifestViewer widget + create_viewer_widget()
factory with _VIEWER_REGISTRY for future viewer classes
Modified files:
- silo_viewproviders.py: doubleClicked() wired to open MDI subwindow
with deduplication via widget objectName()
- CMakeLists.txt: add silo_viewers.py to install list
Closes#38
Add document tree infrastructure that creates Silo metadata nodes when
a .kc file is opened. Nodes appear under a "Silo" group and represent
the silo/ ZIP directory entries (manifest, metadata, history, etc.).
New files:
- silo_objects.py: SiloViewerObject proxy with Transient properties
- silo_viewproviders.py: SiloViewerViewProvider with icon stubs
- silo_tree.py: SiloTreeBuilder with conditional node creation
- silo_document.py: SiloDocumentObserver singleton + registration
Modified files:
- kc_format.py: pre_reinject hook system for silo/ entry mutation
- InitGui.py: 600ms timer registration for document observer
- CMakeLists.txt: install list for 4 new Python files
Closes#37
loadPixmap() rendered all SVGs at a hardcoded 64x64 pixels regardless of
display DPI. On HiDPI screens, Qt then downscaled these low-resolution
pixmaps to the toolbar icon size, producing chunky/aliased icons.
Multiply the render size by getMaximumDPR() and tag the resulting pixmap
with the correct devicePixelRatio, matching the pattern already used in
pixmapFromSvg(const char* name, QSizeF size). This ensures SVGs are
rasterized at the physical resolution needed for crisp display.
Route platform API calls through kindred_sdk wrappers:
ZTools:
- Replace hardcoded MOCHA dict with kindred_sdk.get_theme_tokens()
- Add sdk dependency to package.xml
Silo:
- Replace FreeCADGui.registerEditingOverlay() with kindred_sdk.register_overlay()
- Replace FreeCADGui.addOrigin()/removeOrigin() with kindred_sdk wrappers
- Replace hardcoded _MOCHA palette subset with kindred_sdk.get_theme_tokens()
- Add sdk dependency to package.xml
Create module:
- Replace dock panel boilerplate with kindred_sdk.register_dock_panel()
Behavior is identical before and after — this is a refactor only.
Closes#250
Add mods/sdk/ with the kindred_sdk Python package providing a stable
API layer for addon integration with Kindred Create platform features.
Modules:
- context: editing context/overlay registration wrappers
- theme: YAML-driven palette system (Catppuccin Mocha)
- origin: FileOrigin registration helpers
- dock: deferred dock panel registration
- compat: version detection utilities
The SDK loads at priority 0 (before all other addons) via the existing
manifest-driven loader. Theme colors are defined in a single YAML
palette file instead of hardcoded Python dicts, enabling future theme
support and eliminating color duplication across addons.
Closes#249
Add FreeCAD.getAddonRegistry() function for runtime addon introspection.
Changes to addon_loader.py:
- Add contexts field to AddonManifest for tracking context IDs
- Add register_context() method for addons to declare contexts at runtime
- Add contexts() method returning {context_id: [addon_names]} mapping
- Parse <contexts> element from <kindred> in package.xml
- Add getAddonRegistry() function returning the registry singleton
Changes to Init.py:
- Expose getAddonRegistry as FreeCAD.getAddonRegistry after loading
Usage:
registry = FreeCAD.getAddonRegistry()
registry.get('ztools') # AddonManifest for ztools
registry.loaded() # list of loaded addons
registry.is_loaded('silo') # True/False
registry.contexts() # {context_id: [addon_names]}
Closes#253
Add <kindred> elements to ztools (priority=50) and silo (priority=60)
package.xml files declaring min_create_version, load_priority,
pure_python, and context metadata.
Fix addon_loader.py topological sort to use level-by-level processing
with (priority, name) sorting within each level, replacing
static_order() which did not guarantee deterministic ordering.
Add docs/src/development/package-xml-schema.md documenting the full
field reference, schema example, and backward compatibility notes.
Closes#252
Add addon_loader.py implementing a six-stage pipeline: scan mods/ for
package.xml files, parse standard fields and optional <kindred>
extensions via ElementTree, validate version compatibility, resolve
load order via graphlib.TopologicalSorter (with legacy fallback),
exec() Init.py/InitGui.py, and populate a runtime AddonRegistry
exposed as FreeCAD.KindredAddons.
Replace hard-coded addon lists in Init.py and InitGui.py with calls
to addon_loader.load_addons(). All QTimer-based Silo integration code
in InitGui.py is unchanged.
Backward compatible: addons without <kindred> elements load with no
constraints using the existing ztools-then-silo order.
Closes#248
- Remove hand-crafted kindred-icons/ in favor of auto-generated themed icons
- Add icons/mappings/ with FCAD.csv (Tango palette) and kindred.csv (Catppuccin Mocha)
- Add icons/retheme.py script to remap upstream FreeCAD SVG colors
- Generate icons/themed/ with 1,595 themed SVGs (45,300 color replacements)
- BitmapFactory loads icons/themed/ as highest priority before default icons
- 157-color mapping covers the full Tango palette, interpolating between
4 luminance anchors per color family
Regenerate: python3 icons/retheme.py
During document restore, PropertyLinkList::Restore sets the Group property
on AssemblyObject, triggering onChanged → updateSolveStatus → solve →
validateNewPlacements. At this point joints reference objects that haven't
been restored yet, causing a null pointer dereference (SIGSEGV).
Add an isRestoring() guard to skip solver invocation during restore,
matching the existing pattern in AssemblyLink::onChanged().
The Create module (src/Mod/Create/) was lost from src/Mod/CMakeLists.txt
during the rebase onto upstream FreeCAD 1.2.0-dev. Without it:
- Mod/Create/ is never installed, so the bootstrap that loads ztools
and silo never runs
- mods/ztools/ and mods/silo/ are never installed
- Startup shows 'Ignoring unknown SiloWorkbench/ZToolsWorkbench'
Also adds kc_format.py to the Create install list (was missing).
Change default edge and vertex color from near-black RGB(25,25,25)
to Catppuccin Mocha Subtext0 RGB(166,173,200) — a neutral light
blue-grey with 4.94:1 contrast against the Mocha background.
Update both the compile-time default in ViewParams.h and the
KindredCreate preference pack. The previous purple (#9344ee) had
only 2.91:1 contrast, causing edges to blend into the background
on cylindrical geometry.
Closes#196
Use resizeDocks() to give Database Activity 80% of the vertical space
in the right dock area, keeping Database Auth compact at 120px.
Closes#190, Closes#191
The previous fix (e10841a6c8) passed {"__file__": ...} as the globals
argument to exec(), which replaced the caller's globals dict entirely.
This stripped FreeCAD, FreeCADGui, Workbench, and other names that
modules expect to be available, causing NameError failures across
Material, Tux, Mesh, ReverseEngineering, OpenSCAD, Inspection, Robot,
AddonManager, MeshPart, and others.
Fix by merging __file__ into the caller's globals with
{**globals(), "__file__": str(init_py)} so both __file__ and all
existing names remain available in the executed code.
Set tooltips on tree widget items so hovering reveals the full name
when text is truncated by column width. Covers all code paths:
- createNewItem() — initial item creation (columns 0, 1, 2)
- slotChangeObject() — Label and Label2 property updates
- slotNewDocument() — document item creation
- slotRelabelDocument() — document rename
Closes#193
Use WCAG relative luminance to choose dark or light text color based
on pill background brightness. Bright backgrounds (Green, Yellow,
Mauve, Teal, Peach) now get dark text (#1e1e2e) instead of the
previous fixed light text (#cdd6f4) that caused poor contrast.
Closes#200
DirMod.run_init() and DirModGui.run_init_gui() use exec(code) to run
addon Init.py and InitGui.py files, but don't pass __file__ in the
globals dict. Addons that reference __file__ (e.g. Silo) crash with
NameError: name '__file__' is not defined.
Pass {"__file__": str(init_py)} as the globals argument so __file__
is available in the executed code, matching the behavior of normal
Python module loading.
Convert BreadcrumbToolBar from a QToolBar in the MainWindow toolbar area
to a QFrame overlay at the top-left of each 3D viewport.
Changes:
- BreadcrumbToolBar: change base class from QToolBar to QFrame, use
QHBoxLayout instead of toolbar actions, semi-transparent overlay
background with rounded corners
- MainWindow: remove breadcrumb toolbar creation, toolbar break, and
signal connection
- View3DInventor: create per-view BreadcrumbToolBar as a child of the
GL viewer widget, positioned at (8,8) with event filter to keep it
raised on viewport resize
Each 3D view now has its own breadcrumb instance connected to the
EditingContextResolver singleton. This reclaims the full-width toolbar
row and keeps the editing context visually tied to the viewport.
PartDesign, Sketcher, and Assembly toolbars use
DefaultVisibility::Unavailable and rely on EditingContextResolver to
show them. When switching to these workbenches without a specific editing
state (e.g. PartDesign with no Body activated), no context matches and
all workbench toolbars stay hidden.
Add workbench-level fallback contexts at priority 20 that match when the
workbench is active regardless of editing state:
- partdesign.workbench: shows Helper Features + Sketcher toolbars
- sketcher.workbench: shows Sketcher + Sketcher Tools
- assembly.workbench: shows Assembly toolbar
These fill the gap between object-specific contexts (priority 30+) and
the empty_document fallback (priority 10).
When "Reset All" is used in Preferences, restoreDefaults() clears the
entire User parameter tree via ParameterManager::Clear(). Widgets then
fall back to upstream FreeCAD hardcoded defaults (e.g. light theme,
default units) instead of Kindred Create defaults.
After clearing, apply the KindredCreate preference pack to restore
Create-specific baseline settings (Catppuccin Mocha theme, toolbar
layout, unit preferences, etc.).
Add min-height: 20px to OriginSelectorWidget in KindredCreate.qss so it
renders at the same visual height as the WorkbenchComboBox. The two
widgets use different Qt base classes (QToolButton vs QComboBox) with
different intrinsic size hints, causing a height mismatch in the toolbar.
Adds push_dag() and get_dag() to SiloClient:
- push_dag: PUT /api/items/{pn}/dag with nodes + edges
- get_dag: GET /api/items/{pn}/dag with optional revision filter
Closes#215
When the silo workbench is loaded, Insert Component now opens the
Silo part browser (OpenItemWidget) instead of the OS file dialog.
Users can search both the Silo database and local files to find
components to insert.
Falls back to the OS file dialog if silo-mod is not installed.
Also adds .kc file support to the fallback file dialog filter.
Closes#202
The Create module (src/Mod/Create/) was never included in the build
because src/Mod/CMakeLists.txt did not call add_subdirectory(Create).
This meant:
- Mod/Create/InitGui.py was never installed, so the workbench loader
(setup_kindred_workbenches) that loads silo and ztools never ran
- The install rules for mods/silo/freecad/ and mods/silo/silo-client/
never executed, leaving the silo workbench files missing
- kc_format.py was also not listed in the Create install rule
Fixes the 'Ignoring unknown SiloWorkbench' error on startup.
- QDockWidget::title: add font-weight bold and text-align left to
match ActionGroup header style
- ActionLabel header: add min-width 0 to prevent title clipping
in narrow panels
Applied to both src/Gui/Stylesheets and resources/preferences copies.
Replace 2-color Base→Crust gradient with 3-color Overlay0→Mantle→Overlay0
gradient in both KindredCreate preference pack and CatppuccinMocha theme.
Enables UseBackgroundColorMid for the 3-color effect.
kc_format.py:
- Auto-create silo/manifest.json with default fields (UUID, timestamps,
username) when saving a .kc file that lacks one
- Update modified_at timestamp on each save
- KC_VERSION = 1.0
Platform integration:
- kindred-create.desktop: add application/x-kindred-create MIME type
- kindred-create.xml: register .kc glob patterns with dedicated MIME type
(application/x-kindred-create), separate from .fcstd type
Remove the closeStart preference check so the start page MDI tab
always closes when a document is opened or created. Re-enable
QListView updates before closing to prevent Qt hang during widget
destruction.
Add hideEvent override as a safety net to re-enable disabled
QListView updates whenever the start page is hidden.
Add #include <QApplication> (for qApp macro), #include <QEvent> (for
QEvent::LanguageChange), and #include <Gui/Application.h> (for
Gui::Application::Instance) which were transitively available in
FreeCAD 1.0 but not in 1.2.