From 3b1aa19f05b99f3533dc704182909c6786bcb9f8 Mon Sep 17 00:00:00 2001 From: "Zheng, Lei" Date: Tue, 27 Aug 2019 18:28:08 +0800 Subject: [PATCH] Gui: add class GroupCommand help with grouped command As an example usage, changed StdCmdTreeViewActions to be derived from GroupCommand --- src/Gui/Command.cpp | 83 ++++++++++++++++++++++++++++ src/Gui/Command.h | 33 ++++++++++++ src/Gui/CommandView.cpp | 116 ++++++++++------------------------------ 3 files changed, 145 insertions(+), 87 deletions(-) diff --git a/src/Gui/Command.cpp b/src/Gui/Command.cpp index f95a1797f2..cd5fb7f4cd 100644 --- a/src/Gui/Command.cpp +++ b/src/Gui/Command.cpp @@ -960,6 +960,89 @@ void Command::updateAction(int) { } +//=========================================================================== +// GroupCommand +//=========================================================================== + +GroupCommand::GroupCommand(const char *name) + :Command(name) +{} + +int GroupCommand::addCommand(Command *cmd, bool reg) { + cmds.emplace_back(cmd,cmds.size()); + if(cmd && reg) + Application::Instance->commandManager().addCommand(cmd); + return (int)cmds.size()-1; +} + +Command *GroupCommand::addCommand(const char *name) { + auto cmd = Application::Instance->commandManager().getCommandByName(name); + if(cmd) + addCommand(cmd,false); + return cmd; +} + +Action * GroupCommand::createAction(void) { + ActionGroup* pcAction = new ActionGroup(this, getMainWindow()); + pcAction->setDropDownMenu(true); + pcAction->setExclusive(false); + pcAction->setCheckable(true); + + for(auto &v : cmds) { + if(!v.first) + pcAction->addAction(QString::fromLatin1(""))->setSeparator(true); + else + v.first->addToGroup(pcAction); + } + + pcAction->setProperty("defaultAction", QVariant(0)); + setup(pcAction); + return pcAction; +} + +void GroupCommand::activated(int iMsg) +{ + if(iMsg<0 || iMsg>=(int)cmds.size()) + return; + + auto &v = cmds[iMsg]; + if(!v.first) + return; + + if(triggerSource()!=TriggerChildAction) + v.first->invoke(0); + + Action* cmdAction = v.first->getAction(); + if(_pcAction && cmdAction) { + _pcAction->setProperty("defaultAction", QVariant((int)v.second)); + setup(_pcAction); + } +} + +void GroupCommand::languageChange() { + if (_pcAction) + setup(_pcAction); +} + +void GroupCommand::setup(Action *pcAction) { + + pcAction->setText(QCoreApplication::translate(className(), getMenuText())); + + int idx = pcAction->property("defaultAction").toInt(); + if(idx>=0 && idx<(int)cmds.size() && cmds[idx].first) { + auto cmd = cmds[idx].first; + pcAction->setIcon(BitmapFactory().iconFromTheme(cmd->getPixmap())); + pcAction->setChecked(cmd->getAction()->isChecked(),true); + const char *context = dynamic_cast(cmd) ? cmd->getName() : cmd->className(); + const char *tooltip = cmd->getToolTipText(); + const char *statustip = cmd->getStatusTip(); + if (!statustip || '\0' == *statustip) + statustip = tooltip; + pcAction->setToolTip(QCoreApplication::translate(context,tooltip)); + pcAction->setStatusTip(QCoreApplication::translate(context,statustip)); + } +} + //=========================================================================== // MacroCommand //=========================================================================== diff --git a/src/Gui/Command.h b/src/Gui/Command.h index 247fc43932..2cc1bbe618 100644 --- a/src/Gui/Command.h +++ b/src/Gui/Command.h @@ -610,6 +610,39 @@ private: TriggerSource _trigger = TriggerNone; }; +/** Class to help implement a group command + * + * To use this class, simply add children command in the constructor of your + * derived class by calling addCommand(); + */ +class GuiExport GroupCommand : public Command { +public: + /// Constructor + GroupCommand(const char *name); + + /** Add child command + * @param cmd: child command. Pass null pointer to add a separator. + * @param reg: whether to register the command with CommandManager + * @return Return the command index. + */ + int addCommand(Command *cmd = 0, bool reg=true); + /** Add child command + * @param cmd: child command name. + * @return Return the found command, or NULL if not found. + */ + Command *addCommand(const char *cmdName); + +protected: + virtual void activated(int iMsg); + virtual Gui::Action * createAction(void); + virtual void languageChange(); + + void setup(Action *); + +protected: + std::vector > cmds; +}; + /** The Python command class * This is a special type of command class. It's used to bind a Python command class into the * FreeCAD command framework. diff --git a/src/Gui/CommandView.cpp b/src/Gui/CommandView.cpp index 5610b97b0b..5c7da40dd8 100644 --- a/src/Gui/CommandView.cpp +++ b/src/Gui/CommandView.cpp @@ -3353,98 +3353,40 @@ void StdTreeDrag::activated(int) // Std_TreeViewActions //=========================================================================== // -class StdCmdTreeViewActions : public Gui::Command +class StdCmdTreeViewActions : public GroupCommand { public: - StdCmdTreeViewActions(); - virtual const char* className() const {return "StdCmdTreeViewActions";} -protected: - virtual void activated(int iMsg); - virtual Gui::Action * createAction(void); + StdCmdTreeViewActions() + :GroupCommand("Std_TreeViewActions") + { + sGroup = QT_TR_NOOP("View"); + sMenuText = QT_TR_NOOP("TreeView actions"); + sToolTipText = QT_TR_NOOP("TreeView behavior options and actions"); + sWhatsThis = "Std_TreeViewActions"; + sStatusTip = QT_TR_NOOP("TreeView behavior options and actions"); + eType = 0; + bCanLog = false; - std::vector > cmds; + addCommand(new StdTreeSyncView()); + addCommand(new StdTreeSyncSelection()); + addCommand(new StdTreeSyncPlacement()); + addCommand(new StdTreePreSelection()); + addCommand(new StdTreeRecordSelection()); + + addCommand(); + + addCommand(new StdTreeSingleDocument()); + addCommand(new StdTreeMultiDocument()); + addCommand(new StdTreeCollapseDocument()); + + addCommand(); + + addCommand(new StdTreeDrag(),cmds.size()); + addCommand(new StdTreeSelection(),cmds.size()); + }; + virtual const char* className() const {return "StdCmdTreeViewActions";} }; -StdCmdTreeViewActions::StdCmdTreeViewActions() - : Command("Std_TreeViewActions") -{ - sGroup = QT_TR_NOOP("View"); - sMenuText = QT_TR_NOOP("TreeView actions"); - sToolTipText = QT_TR_NOOP("TreeView behavior options and actions"); - sWhatsThis = "Std_TreeViewActions"; - sStatusTip = QT_TR_NOOP("TreeView behavior options and actions"); - eType = 0; - bCanLog = false; - - CommandManager &mgr = Application::Instance->commandManager(); - cmds.reserve(12); - cmds.emplace_back(new StdTreeSyncView(),cmds.size()); - mgr.addCommand(cmds.back().first); - cmds.emplace_back(new StdTreeSyncSelection(),cmds.size()); - mgr.addCommand(cmds.back().first); - cmds.emplace_back(new StdTreeSyncPlacement(),cmds.size()); - mgr.addCommand(cmds.back().first); - cmds.emplace_back(new StdTreePreSelection(),cmds.size()); - mgr.addCommand(cmds.back().first); - cmds.emplace_back(new StdTreeRecordSelection(),cmds.size()); - mgr.addCommand(cmds.back().first); - - cmds.emplace_back(nullptr,0); - - cmds.emplace_back(new StdTreeSingleDocument(),cmds.size()+1); - mgr.addCommand(cmds.back().first); - cmds.emplace_back(new StdTreeMultiDocument(),cmds.size()+1); - mgr.addCommand(cmds.back().first); - cmds.emplace_back(new StdTreeCollapseDocument(),cmds.size()-2); - mgr.addCommand(cmds.back().first); - - cmds.emplace_back(nullptr,0); - - cmds.emplace_back(new StdTreeDrag(),cmds.size()); - mgr.addCommand(cmds.back().first); - - cmds.emplace_back(new StdTreeSelection(),cmds.size()); - mgr.addCommand(cmds.back().first); -} - -Action * StdCmdTreeViewActions::createAction(void) { - ActionGroup* pcAction = new ActionGroup(this, getMainWindow()); - pcAction->setDropDownMenu(true); - pcAction->setExclusive(false); - applyCommandData(this->className(), pcAction); - pcAction->setCheckable(true); - - for(auto &v : cmds) { - if(!v.first) - pcAction->addAction(QString::fromLatin1(""))->setSeparator(true); - else - v.first->addToGroup(pcAction); - } - pcAction->setIcon(BitmapFactory().iconFromTheme(cmds[0].first->getPixmap())); - pcAction->setChecked(cmds[0].first->getAction()->isChecked(),true); - - return pcAction; -} - -void StdCmdTreeViewActions::activated(int iMsg) -{ - if(iMsg<0 || iMsg>=(int)cmds.size()) - return; - - auto &v = cmds[iMsg]; - if(!v.first) - return; - - if(triggerSource()!=TriggerChildAction) - v.first->invoke(0); - - Action* cmdAction = v.first->getAction(); - if(_pcAction && cmdAction) { - _pcAction->setIcon(BitmapFactory().iconFromTheme(v.first->getPixmap())); - _pcAction->setChecked(cmdAction->isChecked(),true); - _pcAction->setProperty("defaultAction", QVariant((int)v.second)); - } -} //====================================================================== // Std_SelBoundingBox