Wholesale copy of all Kindred Create additions that don't conflict with upstream FreeCAD code: - kindred-icons/ (1444 Catppuccin Mocha SVG icon overrides) - src/Mod/Create/ (Kindred Create workbench) - src/Gui/ Kindred source files (FileOrigin, OriginManager, OriginSelectorWidget, CommandOrigin, BreadcrumbToolBar, EditingContext) - src/Gui/Icons/ (Kindred branding and silo icons) - src/Gui/PreferencePacks/KindredCreate/ - src/Gui/Stylesheets/ (KindredCreate.qss, images_dark-light/) - package/ (rattler-build recipe) - docs/ (architecture, guides, specifications) - .gitea/ (CI workflows, issue templates) - mods/silo, mods/ztools submodules - .gitmodules (Kindred submodule URLs) - resources/ (kindred-create.desktop, kindred-create.xml) - banner-logo-light.png, CONTRIBUTING.md
7.1 KiB
FileOrigin — Abstract Interface
Header:
src/Gui/FileOrigin.hImplementation:src/Gui/FileOrigin.cppNamespace:Gui
FileOrigin is the abstract base class that all document storage backends
implement. It defines the contract for creating, opening, saving, and
tracking FreeCAD documents through a pluggable origin system.
Key Design Principle
Origins do not change where files are stored — all documents are always saved to the local filesystem. Origins change the workflow and identity model:
| Origin | Identity | Tracking | Authentication |
|---|---|---|---|
| Local | File path | None | None |
| PLM (Silo) | Database UUID | External DB + MinIO | Required |
| Cloud | URL / key | External service | Required |
Enums
OriginType
enum class OriginType {
Local, // Local filesystem storage
PLM, // Product Lifecycle Management system (e.g., Silo)
Cloud, // Generic cloud storage
Custom // User-defined origin type
};
ConnectionState
enum class ConnectionState {
Disconnected, // Not connected
Connecting, // Connection in progress
Connected, // Successfully connected
Error // Connection error occurred
};
Used by the OriginSelectorWidget to render status overlays on origin icons.
Pure Virtual Methods (must override)
Every FileOrigin subclass must implement these methods.
Identity
| Method | Return | Purpose |
|---|---|---|
id() |
std::string |
Unique origin ID ("local", "silo", …) |
name() |
std::string |
Display name for menus ("Local Files", "Kindred Silo") |
nickname() |
std::string |
Short label for toolbar ("Local", "Silo") |
icon() |
QIcon |
Icon for UI representation |
type() |
OriginType |
Classification enum |
Workflow Characteristics
| Method | Return | Purpose |
|---|---|---|
tracksExternally() |
bool |
true if origin syncs to a remote system |
requiresAuthentication() |
bool |
true if origin needs login |
Document Identity
| Method | Return | Purpose |
|---|---|---|
documentIdentity(doc) |
std::string |
Immutable tracking key. File path for Local, UUID for PLM. |
documentDisplayId(doc) |
std::string |
Human-readable ID. File path for Local, part number for PLM. |
ownsDocument(doc) |
bool |
Whether this origin owns the document. |
Ownership detection is the mechanism that determines which origin
manages a given document. The
OriginManager calls ownsDocument() on each
registered origin to resolve ownership.
LocalFileOriginowns documents that have noSiloItemIdproperty on any object.SiloOrigin(Python) owns documents where any object has aSiloItemIdproperty.
Core Document Operations
| Method | Parameters | Return | Purpose |
|---|---|---|---|
newDocument |
name = "" |
App::Document* |
Create a new document |
openDocument |
identity |
App::Document* |
Open by identity (non-interactive) |
openDocumentInteractive |
— | App::Document* |
Open via dialog (file picker / search) |
saveDocument |
doc |
bool |
Save document |
saveDocumentAs |
doc, newIdentity |
bool |
Save with new identity |
saveDocumentAsInteractive |
doc |
bool |
Save via dialog |
Returns nullptr / false on failure or cancellation.
Virtual Methods with Defaults (optional overrides)
Capability Queries
These default to false. Override to advertise capabilities that the
CommandOrigin commands check before enabling
menu items.
| Method | Default | Enables |
|---|---|---|
supportsRevisions() |
false |
Commit / Pull / Push commands |
supportsBOM() |
false |
BOM command |
supportsPartNumbers() |
false |
Info command |
supportsAssemblies() |
false |
(reserved for future use) |
Connection State
| Method | Default | Purpose |
|---|---|---|
connectionState() |
Connected |
Current connection state |
connect() |
return true |
Attempt to connect / authenticate |
disconnect() |
no-op | Disconnect from origin |
Extended PLM Operations
These default to no-op / false. Override in PLM origins.
| Method | Default | Purpose |
|---|---|---|
commitDocument(doc) |
false |
Create a versioned snapshot |
pullDocument(doc) |
false |
Fetch latest from remote |
pushDocument(doc) |
false |
Upload changes to remote |
showInfo(doc) |
no-op | Show metadata dialog |
showBOM(doc) |
no-op | Show Bill of Materials dialog |
syncProperties(doc) |
true |
Push property changes to backend |
Signal
fastsignals::signal<void(ConnectionState)> signalConnectionStateChanged;
Origins must emit this signal when their connection state changes. The
OriginSelectorWidget subscribes to it to update the toolbar icon
overlay (green = connected, red X = disconnected, warning = error).
Construction and Lifetime
FileOriginis non-copyable (deleted copy constructor and assignment operator).- The protected default constructor prevents direct instantiation.
- Instances are owned by
OriginManagerviastd::unique_ptr. - Python origins are wrapped by
FileOriginPython(see Python-C++ bridge).
LocalFileOrigin
LocalFileOrigin is the built-in concrete implementation that ships with
Kindred Create. It is always registered by OriginManager as the
"local" origin and serves as the universal fallback.
Behavior Summary
| Method | Behavior |
|---|---|
ownsDocument |
Returns true if no object has a SiloItemId property |
documentIdentity |
Returns doc->FileName (full path) |
newDocument |
Delegates to App::GetApplication().newDocument() |
openDocument |
Delegates to App::GetApplication().openDocument() |
openDocumentInteractive |
Shows standard FreeCAD file-open dialog with format filters |
saveDocument |
Calls doc->save(), returns false if no filename set |
saveDocumentAs |
Calls doc->saveAs() |
saveDocumentAsInteractive |
Calls Gui::Document::saveAs() (shows save dialog) |
Ownership Detection Algorithm
for each object in document:
if object has property "SiloItemId":
return false ← owned by PLM, not local
return true ← local owns this document
This negative-match approach means LocalFileOrigin is the universal
fallback — it owns any document that no other origin claims.
See Also
- OriginManager — singleton registry that manages origin instances
- FileOriginPython — bridge for implementing origins in Python
- CommandOrigin — File menu commands that dispatch to origins
- OriginSelectorWidget — toolbar dropdown for switching origins
- Creating a Custom Origin (C++)
- Creating a Custom Origin (Python)