From 679aaec6d49bf557f01f8e9f86e58bdf568bd9cb Mon Sep 17 00:00:00 2001 From: forbes-0023 Date: Thu, 5 Feb 2026 14:49:22 -0600 Subject: [PATCH] feat(gui): add unified origin commands for PLM operations (#14) - Create CommandOrigin.cpp with Origin_Commit, Origin_Pull, Origin_Push, Origin_Info, Origin_BOM commands - Commands delegate to current origin's extended operations - Commands auto-disable based on origin capabilities (supportsRevisions, supportsBOM, supportsPartNumbers) - Add 'Origin Tools' toolbar with PLM operations - Add origin commands to File menu - Register commands via CreateOriginCommands() in Application startup This implements Issue #14: Dynamic toolbar extension for Silo commands --- src/Gui/Application.cpp | 1 + src/Gui/CMakeLists.txt | 1 + src/Gui/Command.h | 1 + src/Gui/CommandOrigin.cpp | 277 ++++++++++++++++++++++++++++++++++++++ src/Gui/Workbench.cpp | 11 +- 5 files changed, 290 insertions(+), 1 deletion(-) create mode 100644 src/Gui/CommandOrigin.cpp diff --git a/src/Gui/Application.cpp b/src/Gui/Application.cpp index ac7eda9c4d..3cb80e658f 100644 --- a/src/Gui/Application.cpp +++ b/src/Gui/Application.cpp @@ -1022,6 +1022,7 @@ void Application::createStandardOperations() Gui::CreateStructureCommands(); Gui::CreateTestCommands(); Gui::CreateLinkCommands(); + Gui::CreateOriginCommands(); } void Application::slotNewDocument(const App::Document& Doc, bool isMainDoc) diff --git a/src/Gui/CMakeLists.txt b/src/Gui/CMakeLists.txt index c9519eed18..dd4641361c 100644 --- a/src/Gui/CMakeLists.txt +++ b/src/Gui/CMakeLists.txt @@ -529,6 +529,7 @@ SET(Command_CPP_SRCS CommandFeat.cpp CommandMacro.cpp CommandStd.cpp + CommandOrigin.cpp CommandWindow.cpp CommandTest.cpp CommandView.cpp diff --git a/src/Gui/Command.h b/src/Gui/Command.h index f060a3dd86..d0d6e7a0a8 100644 --- a/src/Gui/Command.h +++ b/src/Gui/Command.h @@ -247,6 +247,7 @@ void CreateWindowStdCommands(); void CreateStructureCommands(); void CreateTestCommands(); void CreateLinkCommands(); +void CreateOriginCommands(); /** The CommandBase class diff --git a/src/Gui/CommandOrigin.cpp b/src/Gui/CommandOrigin.cpp new file mode 100644 index 0000000000..dca6b9764a --- /dev/null +++ b/src/Gui/CommandOrigin.cpp @@ -0,0 +1,277 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later + +/*************************************************************************** + * Copyright (c) 2025 Kindred Systems * + * * + * This file is part of FreeCAD. * + * * + * FreeCAD is free software: you can redistribute it and/or modify it * + * under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 2.1 of the * + * License, or (at your option) any later version. * + * * + * FreeCAD is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with FreeCAD. If not, see * + * . * + * * + ***************************************************************************/ + +/** + * @file CommandOrigin.cpp + * @brief Unified origin commands that work with the current origin + * + * These commands delegate to the current FileOrigin's extended operations. + * They are only active when the current origin supports the required capability. + */ + +#include +#include + +#include "Application.h" +#include "BitmapFactory.h" +#include "Command.h" +#include "Document.h" +#include "FileOrigin.h" +#include "MainWindow.h" +#include "OriginManager.h" + + +using namespace Gui; + +//=========================================================================== +// Origin_Commit +//=========================================================================== + +DEF_STD_CMD_A(OriginCmdCommit) + +OriginCmdCommit::OriginCmdCommit() + : Command("Origin_Commit") +{ + sGroup = "File"; + sMenuText = QT_TR_NOOP("&Commit"); + sToolTipText = QT_TR_NOOP("Commit changes as a new revision"); + sWhatsThis = "Origin_Commit"; + sStatusTip = sToolTipText; + sPixmap = "silo-commit"; + sAccel = "Ctrl+Shift+C"; + eType = AlterDoc; +} + +void OriginCmdCommit::activated(int /*iMsg*/) +{ + App::Document* doc = App::GetApplication().getActiveDocument(); + if (!doc) { + return; + } + + FileOrigin* origin = OriginManager::instance()->findOwningOrigin(doc); + if (origin && origin->supportsRevisions()) { + origin->commitDocument(doc); + } +} + +bool OriginCmdCommit::isActive() +{ + App::Document* doc = App::GetApplication().getActiveDocument(); + if (!doc) { + return false; + } + + FileOrigin* origin = OriginManager::instance()->findOwningOrigin(doc); + return origin && origin->supportsRevisions(); +} + +//=========================================================================== +// Origin_Pull +//=========================================================================== + +DEF_STD_CMD_A(OriginCmdPull) + +OriginCmdPull::OriginCmdPull() + : Command("Origin_Pull") +{ + sGroup = "File"; + sMenuText = QT_TR_NOOP("&Pull"); + sToolTipText = QT_TR_NOOP("Pull a specific revision from the origin"); + sWhatsThis = "Origin_Pull"; + sStatusTip = sToolTipText; + sPixmap = "silo-pull"; + sAccel = "Ctrl+Shift+P"; + eType = AlterDoc; +} + +void OriginCmdPull::activated(int /*iMsg*/) +{ + App::Document* doc = App::GetApplication().getActiveDocument(); + if (!doc) { + return; + } + + FileOrigin* origin = OriginManager::instance()->findOwningOrigin(doc); + if (origin && origin->supportsRevisions()) { + origin->pullDocument(doc); + } +} + +bool OriginCmdPull::isActive() +{ + App::Document* doc = App::GetApplication().getActiveDocument(); + if (!doc) { + return false; + } + + FileOrigin* origin = OriginManager::instance()->findOwningOrigin(doc); + return origin && origin->supportsRevisions(); +} + +//=========================================================================== +// Origin_Push +//=========================================================================== + +DEF_STD_CMD_A(OriginCmdPush) + +OriginCmdPush::OriginCmdPush() + : Command("Origin_Push") +{ + sGroup = "File"; + sMenuText = QT_TR_NOOP("Pu&sh"); + sToolTipText = QT_TR_NOOP("Push local changes to the origin"); + sWhatsThis = "Origin_Push"; + sStatusTip = sToolTipText; + sPixmap = "silo-push"; + sAccel = "Ctrl+Shift+U"; + eType = AlterDoc; +} + +void OriginCmdPush::activated(int /*iMsg*/) +{ + App::Document* doc = App::GetApplication().getActiveDocument(); + if (!doc) { + return; + } + + FileOrigin* origin = OriginManager::instance()->findOwningOrigin(doc); + if (origin && origin->supportsRevisions()) { + origin->pushDocument(doc); + } +} + +bool OriginCmdPush::isActive() +{ + App::Document* doc = App::GetApplication().getActiveDocument(); + if (!doc) { + return false; + } + + FileOrigin* origin = OriginManager::instance()->findOwningOrigin(doc); + return origin && origin->supportsRevisions(); +} + +//=========================================================================== +// Origin_Info +//=========================================================================== + +DEF_STD_CMD_A(OriginCmdInfo) + +OriginCmdInfo::OriginCmdInfo() + : Command("Origin_Info") +{ + sGroup = "File"; + sMenuText = QT_TR_NOOP("&Info"); + sToolTipText = QT_TR_NOOP("Show document information from origin"); + sWhatsThis = "Origin_Info"; + sStatusTip = sToolTipText; + sPixmap = "silo-info"; + eType = 0; +} + +void OriginCmdInfo::activated(int /*iMsg*/) +{ + App::Document* doc = App::GetApplication().getActiveDocument(); + if (!doc) { + return; + } + + FileOrigin* origin = OriginManager::instance()->findOwningOrigin(doc); + if (origin && origin->supportsPartNumbers()) { + origin->showInfo(doc); + } +} + +bool OriginCmdInfo::isActive() +{ + App::Document* doc = App::GetApplication().getActiveDocument(); + if (!doc) { + return false; + } + + FileOrigin* origin = OriginManager::instance()->findOwningOrigin(doc); + return origin && origin->supportsPartNumbers(); +} + +//=========================================================================== +// Origin_BOM +//=========================================================================== + +DEF_STD_CMD_A(OriginCmdBOM) + +OriginCmdBOM::OriginCmdBOM() + : Command("Origin_BOM") +{ + sGroup = "File"; + sMenuText = QT_TR_NOOP("&Bill of Materials"); + sToolTipText = QT_TR_NOOP("Show Bill of Materials for this document"); + sWhatsThis = "Origin_BOM"; + sStatusTip = sToolTipText; + sPixmap = "silo-bom"; + eType = 0; +} + +void OriginCmdBOM::activated(int /*iMsg*/) +{ + App::Document* doc = App::GetApplication().getActiveDocument(); + if (!doc) { + return; + } + + FileOrigin* origin = OriginManager::instance()->findOwningOrigin(doc); + if (origin && origin->supportsBOM()) { + origin->showBOM(doc); + } +} + +bool OriginCmdBOM::isActive() +{ + App::Document* doc = App::GetApplication().getActiveDocument(); + if (!doc) { + return false; + } + + FileOrigin* origin = OriginManager::instance()->findOwningOrigin(doc); + return origin && origin->supportsBOM(); +} + + +//=========================================================================== +// Command Registration +//=========================================================================== + +namespace Gui { + +void 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()); +} + +} // namespace Gui diff --git a/src/Gui/Workbench.cpp b/src/Gui/Workbench.cpp index 96b393b58c..93e500fd50 100644 --- a/src/Gui/Workbench.cpp +++ b/src/Gui/Workbench.cpp @@ -682,7 +682,10 @@ MenuItem* StdWorkbench::setupMenuBar() const file->setCommand("&File"); *file << "Std_New" << "Std_Open" << "Std_RecentFiles" << "Separator" << "Std_CloseActiveWindow" << "Std_CloseAllWindows" << "Separator" << "Std_Save" << "Std_SaveAs" - << "Std_SaveCopy" << "Std_SaveAll" << "Std_Revert" << "Separator" << "Std_Import" + << "Std_SaveCopy" << "Std_SaveAll" << "Std_Revert" + << "Separator" << "Origin_Commit" << "Origin_Pull" << "Origin_Push" + << "Origin_Info" << "Origin_BOM" + << "Separator" << "Std_Import" << "Std_Export" << "Std_MergeProjects" << "Std_ProjectInfo" << "Separator" << "Std_Print" << "Std_PrintPreview" << "Std_PrintPdf" << "Separator" << "Std_Quit"; @@ -836,6 +839,12 @@ ToolBarItem* StdWorkbench::setupToolBars() const file->setCommand("File"); *file << "Std_Origin" << "Std_New" << "Std_Open" << "Std_Save"; + // Origin Tools (PLM operations - commands auto-disable when not applicable) + auto originTools = new ToolBarItem(root); + originTools->setCommand("Origin Tools"); + *originTools << "Origin_Commit" << "Origin_Pull" << "Origin_Push" + << "Separator" << "Origin_Info" << "Origin_BOM"; + // Edit auto edit = new ToolBarItem(root); edit->setCommand("Edit");