# FileOrigin — Abstract Interface > **Header:** `src/Gui/FileOrigin.h` > **Implementation:** `src/Gui/FileOrigin.cpp` > **Namespace:** `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` ```cpp 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` ```cpp enum class ConnectionState { Disconnected, // Not connected Connecting, // Connection in progress Connected, // Successfully connected Error // Connection error occurred }; ``` Used by the [OriginSelectorWidget](./cpp-origin-selector-widget.md) 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](./cpp-origin-manager.md) calls `ownsDocument()` on each registered origin to resolve ownership. - `LocalFileOrigin` owns documents that have **no** `SiloItemId` property on any object. - `SiloOrigin` (Python) owns documents where any object **has** a `SiloItemId` property. ### 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](./cpp-command-origin.md) 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 ```cpp fastsignals::signal 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 - `FileOrigin` is non-copyable (deleted copy constructor and assignment operator). - The protected default constructor prevents direct instantiation. - Instances are owned by `OriginManager` via `std::unique_ptr`. - Python origins are wrapped by `FileOriginPython` (see [Python-C++ bridge](./cpp-file-origin-python.md)). ## 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](./cpp-origin-manager.md) — singleton registry that manages origin instances - [FileOriginPython](./cpp-file-origin-python.md) — bridge for implementing origins in Python - [CommandOrigin](./cpp-command-origin.md) — File menu commands that dispatch to origins - [OriginSelectorWidget](./cpp-origin-selector-widget.md) — toolbar dropdown for switching origins - [Creating a Custom Origin (C++)](../guide/custom-origin-cpp.md) - [Creating a Custom Origin (Python)](../guide/custom-origin-python.md)