Gui: add class GroupCommand help with grouped command

As an example usage, changed StdCmdTreeViewActions to be derived from
GroupCommand
This commit is contained in:
Zheng, Lei
2019-08-27 18:28:08 +08:00
committed by wmayer
parent 2fe15c87cf
commit 3b1aa19f05
3 changed files with 145 additions and 87 deletions

View File

@@ -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<PythonCommand*>(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
//===========================================================================

View File

@@ -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<std::pair<Command*,size_t> > 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.

View File

@@ -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<std::pair<Command*,size_t> > 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