Dynamic toolbar extension for Silo commands #14

Closed
opened 2026-02-05 18:28:34 +00:00 by forbes · 1 comment
Owner

Overview

Dynamically show/hide Silo-specific toolbar commands based on the currently selected origin. When a Silo origin is selected, extended commands (Commit, Pull, Push, Info, BOM, etc.) appear in the toolbar. When Local Files is selected, these commands are hidden.

Parent Issue

Epic: #8 Unified File Origin System

Goals

  1. Show Silo-specific commands only when a Silo origin is selected
  2. Smooth visual transition when switching origins
  3. Maintain toolbar organization and visual consistency
  4. Commands should also appear/disappear in menus

Detailed Design

Toolbar Layout

Local Files selected:
┌─────────────────────────────────────────────────────────────────┐
│ [📁 Local ▼] │ [New] [Open] [Save] [SaveAs] │ [Import] [Export] │
└─────────────────────────────────────────────────────────────────┘

Silo origin selected:
┌───────────────────────────────────────────────────────────────────────────────────────┐
│ [☁️ Work ▼] │ [New] [Open] [Save] [SaveAs] │ [Commit] [Pull] [Push] │ [Info] [BOM] │ [Import] [Export] │
└───────────────────────────────────────────────────────────────────────────────────────┘
                                              └── Silo section ──┘   └─ Silo info ─┘

Command Visibility Control

Create a system to register commands with capability requirements:

// src/Gui/OriginCommandManager.h

class OriginCommandManager : public QObject {
    Q_OBJECT
public:
    static OriginCommandManager* instance();
    
    // Register a command with its required capabilities
    void registerOriginCommand(const QString& commandName, 
                                OriginCapabilities requiredCaps);
    
    // Get visibility state for a command
    bool isCommandVisible(const QString& commandName) const;
    
Q_SIGNALS:
    void commandVisibilityChanged();
    
private Q_SLOTS:
    void onCurrentOriginChanged(FileOrigin* origin);
    
private:
    struct CommandInfo {
        QString name;
        OriginCapabilities requiredCaps;
    };
    QList<CommandInfo> m_commands;
};

// Capability flags
enum class OriginCapability {
    None = 0,
    Revisions = 1 << 0,    // Commit, Pull, Push, Rollback
    BOM = 1 << 1,          // BOM viewer
    PartNumbers = 1 << 2,  // Part number generation
    Status = 1 << 3,       // Status workflow
    Auth = 1 << 4,         // Authentication
};
Q_DECLARE_FLAGS(OriginCapabilities, OriginCapability)

Silo Commands to Show/Hide

Command Required Capability Description
Origin_Commit Revisions Save as new revision
Origin_Pull Revisions Pull specific revision
Origin_Push Revisions Push changes
Origin_Rollback Revisions Rollback to previous
Origin_Info PartNumbers View item info
Origin_BOM BOM Bill of Materials
Origin_SetStatus Status Set revision status
Origin_Auth Auth Authentication status

Implementation Approach

Option A: Dynamic Action Visibility

void OriginCommandManager::onCurrentOriginChanged(FileOrigin* origin) {
    OriginCapabilities caps = origin->capabilities();
    
    for (const CommandInfo& cmd : m_commands) {
        bool visible = (caps & cmd.requiredCaps) == cmd.requiredCaps;
        
        // Update action visibility in all toolbars/menus
        if (QAction* action = getActionForCommand(cmd.name)) {
            action->setVisible(visible);
        }
    }
    
    Q_EMIT commandVisibilityChanged();
}

Option B: Separate Toolbar Section

Create a dedicated "Origin Tools" toolbar section that gets populated based on origin:

void MainWindow::updateOriginToolbar(FileOrigin* origin) {
    QToolBar* originToolbar = findChild<QToolBar*>("OriginTools");
    originToolbar->clear();
    
    if (origin->supportsRevisions()) {
        originToolbar->addAction(getAction("Origin_Commit"));
        originToolbar->addAction(getAction("Origin_Pull"));
        originToolbar->addAction(getAction("Origin_Push"));
    }
    
    if (origin->supportsBOM()) {
        originToolbar->addSeparator();
        originToolbar->addAction(getAction("Origin_Info"));
        originToolbar->addAction(getAction("Origin_BOM"));
    }
    
    originToolbar->setVisible(!originToolbar->actions().isEmpty());
}

New Commands

Create new unified commands that replace Silo_* commands:

// These delegate to current origin's extended operations
class OriginCmdCommit : public Command {
    void activated(int) override {
        auto* doc = App::GetApplication().getActiveDocument();
        auto* origin = OriginManager::instance()->originForDocument(doc);
        if (origin && origin->supportsRevisions()) {
            origin->commitDocument(doc);
        }
    }
    
    bool isActive() override {
        auto* origin = OriginManager::instance()->currentOrigin();
        return origin && origin->supportsRevisions();
    }
};

Menu Integration

Also update File menu to show/hide Silo items:

File Menu (Local):          File Menu (Silo):
├── New                     ├── New
├── Open                    ├── Open  
├── Save                    ├── Save
├── Save As                 ├── Save As
├── ─────────               ├── ─────────
├── Import                  ├── Commit          ← Added
├── Export                  ├── Pull            ← Added
├── ─────────               ├── Push            ← Added
├── Close                   ├── ─────────
└── Exit                    ├── Import
                            ├── Export
                            ├── ─────────
                            ├── Close
                            └── Exit

Implementation Tasks

  • Create OriginCommandManager class
  • Define OriginCapability flags
  • Create unified Origin_* commands
  • Register commands with capability requirements
  • Implement visibility updates on origin change
  • Update File menu dynamically
  • Create/update toolbar sections
  • Migrate Silo_* commands to new system
  • Add keyboard shortcuts for new commands
  • Test visibility transitions

Files to Create/Modify

  • src/Gui/OriginCommandManager.h (new)
  • src/Gui/OriginCommandManager.cpp (new)
  • src/Gui/CommandOrigin.cpp (new - unified origin commands)
  • src/Gui/MainWindow.cpp (toolbar updates)
  • src/Gui/Application.cpp (menu updates)

Acceptance Criteria

  • Silo commands hidden when Local origin selected
  • Silo commands visible when Silo origin selected
  • Smooth transition (no flickering)
  • Toolbar reorganizes cleanly
  • Menu updates match toolbar
  • Commands disabled (not just hidden) when not applicable
  • Keyboard shortcuts work when commands visible
  • No orphaned separators when commands hidden

Dependencies

  • #9 Origin abstraction layer
  • #11 Silo origin adapter
  • #13 Origin selector widget

Blocking

None - this completes Phase 2

## Overview Dynamically show/hide Silo-specific toolbar commands based on the currently selected origin. When a Silo origin is selected, extended commands (Commit, Pull, Push, Info, BOM, etc.) appear in the toolbar. When Local Files is selected, these commands are hidden. ## Parent Issue Epic: #8 Unified File Origin System ## Goals 1. Show Silo-specific commands only when a Silo origin is selected 2. Smooth visual transition when switching origins 3. Maintain toolbar organization and visual consistency 4. Commands should also appear/disappear in menus ## Detailed Design ### Toolbar Layout ``` Local Files selected: ┌─────────────────────────────────────────────────────────────────┐ │ [📁 Local ▼] │ [New] [Open] [Save] [SaveAs] │ [Import] [Export] │ └─────────────────────────────────────────────────────────────────┘ Silo origin selected: ┌───────────────────────────────────────────────────────────────────────────────────────┐ │ [☁️ Work ▼] │ [New] [Open] [Save] [SaveAs] │ [Commit] [Pull] [Push] │ [Info] [BOM] │ [Import] [Export] │ └───────────────────────────────────────────────────────────────────────────────────────┘ └── Silo section ──┘ └─ Silo info ─┘ ``` ### Command Visibility Control Create a system to register commands with capability requirements: ```cpp // src/Gui/OriginCommandManager.h class OriginCommandManager : public QObject { Q_OBJECT public: static OriginCommandManager* instance(); // Register a command with its required capabilities void registerOriginCommand(const QString& commandName, OriginCapabilities requiredCaps); // Get visibility state for a command bool isCommandVisible(const QString& commandName) const; Q_SIGNALS: void commandVisibilityChanged(); private Q_SLOTS: void onCurrentOriginChanged(FileOrigin* origin); private: struct CommandInfo { QString name; OriginCapabilities requiredCaps; }; QList<CommandInfo> m_commands; }; // Capability flags enum class OriginCapability { None = 0, Revisions = 1 << 0, // Commit, Pull, Push, Rollback BOM = 1 << 1, // BOM viewer PartNumbers = 1 << 2, // Part number generation Status = 1 << 3, // Status workflow Auth = 1 << 4, // Authentication }; Q_DECLARE_FLAGS(OriginCapabilities, OriginCapability) ``` ### Silo Commands to Show/Hide | Command | Required Capability | Description | |---------|-------------------|-------------| | `Origin_Commit` | Revisions | Save as new revision | | `Origin_Pull` | Revisions | Pull specific revision | | `Origin_Push` | Revisions | Push changes | | `Origin_Rollback` | Revisions | Rollback to previous | | `Origin_Info` | PartNumbers | View item info | | `Origin_BOM` | BOM | Bill of Materials | | `Origin_SetStatus` | Status | Set revision status | | `Origin_Auth` | Auth | Authentication status | ### Implementation Approach #### Option A: Dynamic Action Visibility ```cpp void OriginCommandManager::onCurrentOriginChanged(FileOrigin* origin) { OriginCapabilities caps = origin->capabilities(); for (const CommandInfo& cmd : m_commands) { bool visible = (caps & cmd.requiredCaps) == cmd.requiredCaps; // Update action visibility in all toolbars/menus if (QAction* action = getActionForCommand(cmd.name)) { action->setVisible(visible); } } Q_EMIT commandVisibilityChanged(); } ``` #### Option B: Separate Toolbar Section Create a dedicated "Origin Tools" toolbar section that gets populated based on origin: ```cpp void MainWindow::updateOriginToolbar(FileOrigin* origin) { QToolBar* originToolbar = findChild<QToolBar*>("OriginTools"); originToolbar->clear(); if (origin->supportsRevisions()) { originToolbar->addAction(getAction("Origin_Commit")); originToolbar->addAction(getAction("Origin_Pull")); originToolbar->addAction(getAction("Origin_Push")); } if (origin->supportsBOM()) { originToolbar->addSeparator(); originToolbar->addAction(getAction("Origin_Info")); originToolbar->addAction(getAction("Origin_BOM")); } originToolbar->setVisible(!originToolbar->actions().isEmpty()); } ``` ### New Commands Create new unified commands that replace `Silo_*` commands: ```cpp // These delegate to current origin's extended operations class OriginCmdCommit : public Command { void activated(int) override { auto* doc = App::GetApplication().getActiveDocument(); auto* origin = OriginManager::instance()->originForDocument(doc); if (origin && origin->supportsRevisions()) { origin->commitDocument(doc); } } bool isActive() override { auto* origin = OriginManager::instance()->currentOrigin(); return origin && origin->supportsRevisions(); } }; ``` ### Menu Integration Also update File menu to show/hide Silo items: ``` File Menu (Local): File Menu (Silo): ├── New ├── New ├── Open ├── Open ├── Save ├── Save ├── Save As ├── Save As ├── ───────── ├── ───────── ├── Import ├── Commit ← Added ├── Export ├── Pull ← Added ├── ───────── ├── Push ← Added ├── Close ├── ───────── └── Exit ├── Import ├── Export ├── ───────── ├── Close └── Exit ``` ## Implementation Tasks - [ ] Create `OriginCommandManager` class - [ ] Define `OriginCapability` flags - [ ] Create unified `Origin_*` commands - [ ] Register commands with capability requirements - [ ] Implement visibility updates on origin change - [ ] Update File menu dynamically - [ ] Create/update toolbar sections - [ ] Migrate `Silo_*` commands to new system - [ ] Add keyboard shortcuts for new commands - [ ] Test visibility transitions ## Files to Create/Modify - `src/Gui/OriginCommandManager.h` (new) - `src/Gui/OriginCommandManager.cpp` (new) - `src/Gui/CommandOrigin.cpp` (new - unified origin commands) - `src/Gui/MainWindow.cpp` (toolbar updates) - `src/Gui/Application.cpp` (menu updates) ## Acceptance Criteria - [ ] Silo commands hidden when Local origin selected - [ ] Silo commands visible when Silo origin selected - [ ] Smooth transition (no flickering) - [ ] Toolbar reorganizes cleanly - [ ] Menu updates match toolbar - [ ] Commands disabled (not just hidden) when not applicable - [ ] Keyboard shortcuts work when commands visible - [ ] No orphaned separators when commands hidden ## Dependencies - #9 Origin abstraction layer - #11 Silo origin adapter - #13 Origin selector widget ## Blocking None - this completes Phase 2
Author
Owner

Complete. Closing with code references:

  • src/Gui/CommandOrigin.cpp (277 lines) — 5 capability-gated commands:
    • Origin_Commit / Origin_Pull / Origin_Push — visible when supportsRevisions()
    • Origin_Info — visible when supportsPartNumbers()
    • Origin_BOM — visible when supportsBOM()
  • src/Gui/Application.cpp:1025CreateOriginCommands() registration
  • src/Gui/Workbench.cpp — Origin commands added to toolbar/menu layout
Complete. Closing with code references: - `src/Gui/CommandOrigin.cpp` (277 lines) — 5 capability-gated commands: - `Origin_Commit` / `Origin_Pull` / `Origin_Push` — visible when `supportsRevisions()` - `Origin_Info` — visible when `supportsPartNumbers()` - `Origin_BOM` — visible when `supportsBOM()` - `src/Gui/Application.cpp:1025` — `CreateOriginCommands()` registration - `src/Gui/Workbench.cpp` — Origin commands added to toolbar/menu layout
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: kindred/create#14