# CommandOrigin — File Menu Origin Commands > **Source:** `src/Gui/CommandOrigin.cpp` > **Namespace:** `Gui` > **Registration:** `Gui::CreateOriginCommands()` Five FreeCAD commands expose the extended operations defined by [FileOrigin](./cpp-file-origin.md). Each command follows the same pattern: look up the owning origin for the active document via [OriginManager](./cpp-origin-manager.md), check whether that origin advertises the required capability, and dispatch to the corresponding `FileOrigin` virtual method. ## Command Table | Command ID | Menu Text | Shortcut | Capability Gate | Dispatches To | Icon | |-----------|-----------|----------|-----------------|---------------|------| | `Origin_Commit` | &Commit | `Ctrl+Shift+C` | `supportsRevisions()` | `commitDocument(doc)` | `silo-commit` | | `Origin_Pull` | &Pull | `Ctrl+Shift+P` | `supportsRevisions()` | `pullDocument(doc)` | `silo-pull` | | `Origin_Push` | Pu&sh | `Ctrl+Shift+U` | `supportsRevisions()` | `pushDocument(doc)` | `silo-push` | | `Origin_Info` | &Info | — | `supportsPartNumbers()` | `showInfo(doc)` | `silo-info` | | `Origin_BOM` | &Bill of Materials | — | `supportsBOM()` | `showBOM(doc)` | `silo-bom` | All commands belong to the `"File"` group. ## Activation Pattern Every command shares the same `isActive()` / `activated()` structure: ``` isActive(): doc = App::GetApplication().getActiveDocument() if doc is null → return false origin = OriginManager::instance()->findOwningOrigin(doc) return origin != null AND origin->supportsXxx() activated(): doc = App::GetApplication().getActiveDocument() if doc is null → return origin = OriginManager::instance()->findOwningOrigin(doc) if origin AND origin->supportsXxx(): origin->xxxDocument(doc) ``` This means the commands **automatically grey out** in the menu when: - No document is open. - The active document is owned by an origin that doesn't support the capability (e.g., a local document has no Commit/Pull/Push). For a local-only document, all five commands are inactive. When a Silo document is active, all five become available because [SiloOrigin](../reference/cpp-file-origin.md) returns `true` for `supportsRevisions()`, `supportsBOM()`, and `supportsPartNumbers()`. ## Ownership Resolution The commands use `findOwningOrigin(doc)` rather than `currentOrigin()` because the active document may belong to a **different** origin than the one currently selected in the toolbar. For example, a user might have Silo selected as the current origin but be viewing a local document in another tab — the commands correctly detect that the local document has no revision support. See [OriginManager § Document-Origin Resolution](./cpp-origin-manager.md#document-origin-resolution) for the full lookup algorithm. ## Command Type Flags | Command | `eType` | Meaning | |---------|---------|---------| | Commit | `AlterDoc` | Marks document as modified (undo integration) | | Pull | `AlterDoc` | Marks document as modified | | Push | `AlterDoc` | Marks document as modified | | Info | `0` | Read-only, no undo integration | | BOM | `0` | Read-only, no undo integration | `AlterDoc` commands participate in FreeCAD's transaction/undo system. Info and BOM are view-only dialogs that don't modify the document. ## Registration All five commands are registered in a single function called during application startup: ```cpp void Gui::CreateOriginCommands() { CommandManager& rcCmdMgr = Application::Instance->commandManager(); rcCmdMgr.addCommand(new OriginCmdCommit()); rcCmdMgr.addCommand(new OriginCmdPull()); rcCmdMgr.addCommand(new OriginCmdPush()); rcCmdMgr.addCommand(new OriginCmdInfo()); rcCmdMgr.addCommand(new OriginCmdBOM()); } ``` This is called from the Gui module initialization alongside other command registration functions (`CreateDocCommands`, `CreateMacroCommands`, etc.). ## What the Commands Actually Do The C++ commands are **thin dispatchers** — they contain no business logic. The actual work happens in the origin implementation: - **Local origin** — all five extended methods are no-ops (defaults from `FileOrigin` base class return `false` or do nothing). - **Silo origin** (Python) — each method delegates to the corresponding `Silo_*` FreeCAD command: | C++ dispatch | Python SiloOrigin method | Delegates to | |-------------|-------------------------|--------------| | `commitDocument()` | `SiloOrigin.commitDocument()` | `Silo_Commit` command | | `pullDocument()` | `SiloOrigin.pullDocument()` | `Silo_Pull` command | | `pushDocument()` | `SiloOrigin.pushDocument()` | `Silo_Push` command | | `showInfo()` | `SiloOrigin.showInfo()` | `Silo_Info` command | | `showBOM()` | `SiloOrigin.showBOM()` | `Silo_BOM` command | The call chain for a Commit, for example: ``` User clicks File > Commit (or Ctrl+Shift+C) → OriginCmdCommit::activated() → OriginManager::findOwningOrigin(doc) [C++] → SiloOrigin.ownsDocument(doc) [Python via bridge] → origin->commitDocument(doc) [C++ virtual] → FileOriginPython::commitDocument(doc) [bridge] → SiloOrigin.commitDocument(doc) [Python] → FreeCADGui.runCommand("Silo_Commit") [Python command] ``` ## See Also - [FileOrigin Interface](./cpp-file-origin.md) — defines the virtual methods these commands dispatch to - [OriginManager](./cpp-origin-manager.md) — provides `findOwningOrigin()` used by every command - [FileOriginPython](./cpp-file-origin-python.md) — bridges the dispatch from C++ to Python origins - [SiloOrigin adapter](./cpp-file-origin.md) — Python implementation that handles the actual Silo operations