From: sbh Date: Wed, 23 Apr 2014 11:10:24 +0000 (+0400) Subject: Issue #6 Disable commands on operation start X-Git-Tag: V_0.2~118^2~10 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=d34bcbd026e31b8cd22468f77ca977abac752162;p=modules%2Fshaper.git Issue #6 Disable commands on operation start --- diff --git a/src/Config/Config_FeatureMessage.cpp b/src/Config/Config_FeatureMessage.cpp index 85102857b..209bb7aa2 100644 --- a/src/Config/Config_FeatureMessage.cpp +++ b/src/Config/Config_FeatureMessage.cpp @@ -95,3 +95,13 @@ void Config_FeatureMessage::setPluginLibrary(const std::string& myPluginLibrary) { this->myPluginLibrary = myPluginLibrary; } + +bool Config_FeatureMessage::isUseInput() const +{ + return myUseInput; +} + +void Config_FeatureMessage::setUseInput(bool isUseInput) +{ + myUseInput = isUseInput; +} diff --git a/src/Config/Config_FeatureMessage.h b/src/Config/Config_FeatureMessage.h index 4185b4b96..900d547d3 100644 --- a/src/Config/Config_FeatureMessage.h +++ b/src/Config/Config_FeatureMessage.h @@ -23,6 +23,8 @@ class Config_FeatureMessage: public Event_Message std::string myWorkbenchId; //Id of feature's workbench std::string myPluginLibrary; //Name of feature's library + bool myUseInput; //Action is being checked until user commit the operation + public: //const Event_ID theID, const void* theSender = 0 CONFIG_EXPORT Config_FeatureMessage(const Event_ID theId, const void* theParent = 0); @@ -50,6 +52,8 @@ public: CONFIG_EXPORT void setGroupId(const std::string& groupId); CONFIG_EXPORT void setWorkbenchId(const std::string& workbenchId); CONFIG_EXPORT void setPluginLibrary(const std::string& thePluginLibrary); + CONFIG_EXPORT bool isUseInput() const; + CONFIG_EXPORT void setUseInput(bool isUseInput); }; #endif // CONFIG_MESSAGE_H diff --git a/src/Config/Config_FeatureReader.cpp b/src/Config/Config_FeatureReader.cpp index bb52b413f..50d72e992 100644 --- a/src/Config/Config_FeatureReader.cpp +++ b/src/Config/Config_FeatureReader.cpp @@ -43,6 +43,8 @@ void Config_FeatureReader::processNode(xmlNodePtr theNode) Event_Loop* aEvLoop = Event_Loop::loop(); Config_FeatureMessage aMessage(aMenuItemEvent, this); fillFeature(theNode, aMessage); + //If a feature has xml definition for it's widget: + aMessage.setUseInput(hasChild(theNode)); aEvLoop->send(aMessage); } //The m_last* variables always defined before fillFeature() call. XML is a tree. diff --git a/src/ModuleBase/ModuleBase_Operation.cpp b/src/ModuleBase/ModuleBase_Operation.cpp index a6afc4d5f..912f930d0 100644 --- a/src/ModuleBase/ModuleBase_Operation.cpp +++ b/src/ModuleBase/ModuleBase_Operation.cpp @@ -247,6 +247,19 @@ void ModuleBase_Operation::commit() emit stopped(); } +/* + * \brief Alias for start/abort slots + * + * Public slot. Aborts operation if false, else does nothing. + * Provided for S/S compatibility with QAction's toggle(bool) + */ +void ModuleBase_Operation::setRunning(bool on) +{ + if (!on) { + abort(); + } +} + /*! * \brief Stores a real value in model. * \param theValue - to store diff --git a/src/ModuleBase/ModuleBase_Operation.h b/src/ModuleBase/ModuleBase_Operation.h index 5daf8e6c6..8789e577e 100644 --- a/src/ModuleBase/ModuleBase_Operation.h +++ b/src/ModuleBase/ModuleBase_Operation.h @@ -106,6 +106,10 @@ public slots: void abort(); void commit(); + //true = do nothing, false = abort() + //Provided for S/S compatibility with QAction's toggle(bool) + void setRunning(bool); + // Data model operations. void storeReal(double); diff --git a/src/PartSet/PartSet_Module.cpp b/src/PartSet/PartSet_Module.cpp index fb437c5ba..4c1bcfbde 100644 --- a/src/PartSet/PartSet_Module.cpp +++ b/src/PartSet/PartSet_Module.cpp @@ -32,36 +32,45 @@ PartSet_Module::~PartSet_Module() void PartSet_Module::createFeatures() { - Config_ModuleReader* aXMLReader = new Config_ModuleReader(); - aXMLReader->setAutoImport(true); - aXMLReader->readAll(); - delete aXMLReader; + Config_ModuleReader aXMLReader = Config_ModuleReader(); + aXMLReader.setAutoImport(true); + aXMLReader.readAll(); } void PartSet_Module::featureCreated(XGUI_Command* theFeature) { - QString aFtId = theFeature->id(); theFeature->connectTo(this, SLOT(onFeatureTriggered())); } -void PartSet_Module::onFeatureTriggered() +std::string PartSet_Module::modulePlugin() { Config_ModuleReader aModuleReader = Config_ModuleReader(); aModuleReader.readAll(); - std::map aPluginMap = aModuleReader.plugins(); + std::map < std::string, std::string > aPluginMap = aModuleReader.plugins(); std::string aPluginName = aPluginMap["PartSetPlugin"]; + return aPluginName; +} + +/* + * + */ +void PartSet_Module::onFeatureTriggered() +{ + std::string aPluginName = modulePlugin(); Config_WidgetReader aWdgReader = Config_WidgetReader(aPluginName); aWdgReader.readAll(); XGUI_Command* aCmd = dynamic_cast(sender()); QString aCmdId = aCmd->id(); std::string aXmlCfg = aWdgReader.featureWidgetCfg(aCmdId.toStdString()); std::string aDescription = aWdgReader.featureDescription(aCmdId.toStdString()); - //TODO(sbh): Implement static method to extract event id [SEID] - static Event_ID aModuleEvent = Event_Loop::eventByName("PartSetModuleEvent"); - Config_PointerMessage aMessage(aModuleEvent, this); + ModuleBase_PropPanelOperation* aPartSetOp = new ModuleBase_PropPanelOperation(aCmdId, this); aPartSetOp->setXmlRepresentation(QString::fromStdString(aXmlCfg)); aPartSetOp->setDescription(QString::fromStdString(aDescription)); + + //TODO(sbh): Implement static method to extract event id [SEID] + static Event_ID aModuleEvent = Event_Loop::eventByName("PartSetModuleEvent"); + Config_PointerMessage aMessage(aModuleEvent, this); aMessage.setPointer(aPartSetOp); Event_Loop::loop()->send(aMessage); } diff --git a/src/PartSet/PartSet_Module.h b/src/PartSet/PartSet_Module.h index f4894e239..c6b895b90 100644 --- a/src/PartSet/PartSet_Module.h +++ b/src/PartSet/PartSet_Module.h @@ -11,6 +11,8 @@ class PARTSET_EXPORT PartSet_Module: public QObject, public XGUI_Module { Q_OBJECT + std::string modulePlugin(); + public: PartSet_Module(XGUI_Workshop* theWshop); virtual ~PartSet_Module(); diff --git a/src/XGUI/XGUI_Command.cpp b/src/XGUI/XGUI_Command.cpp index 5e9ffb8fb..ffd6ab103 100644 --- a/src/XGUI/XGUI_Command.cpp +++ b/src/XGUI/XGUI_Command.cpp @@ -2,14 +2,14 @@ #include -XGUI_Command::XGUI_Command(const QString& theId, QObject * parent) - : QWidgetAction(parent), myId(theId) +XGUI_Command::XGUI_Command(const QString& theId, QObject * parent, bool isCheckable) + : QWidgetAction(parent), myId(theId), myCheckable(isCheckable) { } XGUI_Command::XGUI_Command(const QString& theId, const QIcon& icon, const QString& text, - QObject* parent) - : QWidgetAction(parent), myId(theId) + QObject* parent, bool isCheckable) + : QWidgetAction(parent), myId(theId), myCheckable(isCheckable) { setIcon(icon); setText(text); @@ -22,22 +22,26 @@ XGUI_Command::~XGUI_Command() QWidget* XGUI_Command::createWidget(QWidget* theParent) { if (theParent->inherits("XGUI_MenuGroupPanel")) { - QPushButton* aBtn = new QPushButton(theParent); - aBtn->setIcon(icon()); - aBtn->setText(text()); - aBtn->setStyleSheet("text-align: left"); + QPushButton* aButton = new QPushButton(theParent); + aButton->setIcon(icon()); + aButton->setText(text()); + aButton->setStyleSheet("text-align: left"); QKeySequence aKeys = shortcut(); QString aToolTip = toolTip(); if (!aKeys.isEmpty()) aToolTip = aToolTip + " (" + aKeys.toString() + ")"; if (!aToolTip.isEmpty()) - aBtn->setToolTip(aToolTip); + aButton->setToolTip(aToolTip); - aBtn->addAction(this); - connect(aBtn, SIGNAL(clicked()), this, SLOT(trigger())); - aBtn->setFlat(true); - aBtn->setMinimumSize(MIN_BUTTON_WIDTH, MIN_BUTTON_HEIGHT); - return aBtn; + aButton->addAction(this); + connect(aButton, SIGNAL(clicked()), this, SLOT(trigger())); + connect(this, SIGNAL(toggled(bool)), aButton, SLOT(setChecked(bool))); + aButton->setFlat(true); + aButton->setCheckable(myCheckable); + this->setCheckable(myCheckable); + aButton->setMinimumSize(MIN_BUTTON_WIDTH, MIN_BUTTON_HEIGHT); + + return aButton; } return QWidgetAction::createWidget(theParent); } @@ -59,5 +63,15 @@ void XGUI_Command::disable() void XGUI_Command::connectTo(const QObject* theResiver, const char* theSlot) { - connect(this, SIGNAL(triggered()), theResiver, theSlot); + connect(this, SIGNAL(triggered()), theResiver, theSlot); +} + +const QStringList& XGUI_Command::unblockableCommands() const +{ + return myUnblockableCommands; +} + +void XGUI_Command::setUnblockableCommands(const QStringList& myUnblockableCommands) +{ + this->myUnblockableCommands = myUnblockableCommands; } diff --git a/src/XGUI/XGUI_Command.h b/src/XGUI/XGUI_Command.h index 34c5f63f6..380b64ae4 100644 --- a/src/XGUI/XGUI_Command.h +++ b/src/XGUI/XGUI_Command.h @@ -15,8 +15,8 @@ class XGUI_EXPORT XGUI_Command: public QWidgetAction { Q_OBJECT public: - XGUI_Command(const QString& theId, QObject * parent); - XGUI_Command(const QString& theId, const QIcon& icon, const QString& text, QObject* parent); + XGUI_Command(const QString& theId, QObject * parent, bool isCheckable = false); + XGUI_Command(const QString& theId, const QIcon& icon, const QString& text, QObject* parent, bool isCheckable = false); ~XGUI_Command(); //! Returns true if the command is enabled @@ -34,6 +34,9 @@ public: return myId; } + const QStringList& unblockableCommands() const; + void setUnblockableCommands(const QStringList& myUnblockableCommands); + //! Connect the command to a slot virtual void connectTo(const QObject* theResiver, const char* theSlot); @@ -43,6 +46,9 @@ protected: private: QString myId; + bool myCheckable; + //! List of Ids of commands which WILL NOT be blocked when the command is on. + QStringList myUnblockableCommands; }; #endif diff --git a/src/XGUI/XGUI_MainMenu.cpp b/src/XGUI/XGUI_MainMenu.cpp index 7d8e81f35..96106a911 100644 --- a/src/XGUI/XGUI_MainMenu.cpp +++ b/src/XGUI/XGUI_MainMenu.cpp @@ -1,6 +1,7 @@ -#include "XGUI_MainMenu.h" -#include "XGUI_Workbench.h" -#include "XGUI_MainWindow.h" +#include +#include +#include +#include #include #include @@ -88,4 +89,50 @@ QList XGUI_MainMenu::features() const aList.append(aWbn->features()); } return aList; -} \ No newline at end of file +} + +void XGUI_MainMenu::onFeatureChecked(bool isChecked) +{ + if (!isChecked) { + restoreCommandState(); + return; + } + + saveCommandsState(); + QStringList aSkippedIds; + XGUI_Command* aToggledFeature = dynamic_cast(sender()); + aSkippedIds.append(aToggledFeature->unblockableCommands()); +// aSkippedIds.append(aToggledFeature->id()); + XGUI_Workbench* aGeneralWB = findWorkbench(tr("General")); + foreach(XGUI_Command* eachFeature, aGeneralWB->features()) { + aSkippedIds.append(eachFeature->id()); + } + QList allFeatures = features(); + foreach(XGUI_Command* eachFeature, allFeatures) { + QString aFeatureId = eachFeature->id(); + if (aSkippedIds.removeAll(aFeatureId) > 0) { + continue; + } + eachFeature->setEnabled(false); + } +} + +void XGUI_MainMenu::saveCommandsState() +{ + myCommandState.clear(); + QList allFeatures = features(); + XGUI_Command* eachFeature = NULL; + foreach(eachFeature, allFeatures) { + myCommandState.insert(eachFeature, eachFeature->enabled()); + } +} + +void XGUI_MainMenu::restoreCommandState() +{ + QList allFeatures = features(); + XGUI_Command* eachFeature = NULL; + foreach(eachFeature, allFeatures) { + eachFeature->setChecked(false); + eachFeature->setEnabled(myCommandState[eachFeature]); + } +} diff --git a/src/XGUI/XGUI_MainMenu.h b/src/XGUI/XGUI_MainMenu.h index c281422a6..0fed1a07f 100644 --- a/src/XGUI/XGUI_MainMenu.h +++ b/src/XGUI/XGUI_MainMenu.h @@ -4,6 +4,7 @@ #include "XGUI.h" #include #include +#include class XGUI_Command; class XGUI_MainWindow; @@ -16,6 +17,7 @@ class QAction; class QDockWidget; class QEvent; + /**\class XGUI_MainMenu * \ingroup GUI * \brief Class for creation of main menu (set of workbenches) @@ -45,13 +47,20 @@ public: //! Returns list of created commands QList features() const; -protected: +public slots: + void onFeatureChecked(bool); + + void saveCommandsState(); + void restoreCommandState(); + virtual bool eventFilter(QObject *theWatched, QEvent *theEvent); private: XGUI_MainWindow* myDesktop; QList myMenuTabs; XGUI_Workbench* myGeneralPage; + + QMap myCommandState; }; #endif diff --git a/src/XGUI/XGUI_MenuGroupPanel.cpp b/src/XGUI/XGUI_MenuGroupPanel.cpp index 00d131278..4f4673470 100644 --- a/src/XGUI/XGUI_MenuGroupPanel.cpp +++ b/src/XGUI/XGUI_MenuGroupPanel.cpp @@ -7,6 +7,7 @@ #include #include +#include XGUI_MenuGroupPanel::XGUI_MenuGroupPanel(QWidget *parent) : QWidget(parent), myNewRow(0), myNewCol(0), myMaxRow(1) @@ -61,9 +62,9 @@ void XGUI_MenuGroupPanel::resizeEvent(QResizeEvent* theEvent) XGUI_Command* XGUI_MenuGroupPanel::addFeature(const QString& theId, const QString& theTitle, const QString& theTip, const QIcon& theIcon, - const QKeySequence& theKeys) + const QKeySequence& theKeys, bool isCheckable) { - XGUI_Command* aCommand = new XGUI_Command(theId, theIcon, theTitle, this); + XGUI_Command* aCommand = new XGUI_Command(theId, theIcon, theTitle, this, isCheckable); aCommand->setToolTip(theTip); if (!theKeys.isEmpty()) aCommand->setShortcut(theKeys); @@ -80,4 +81,4 @@ XGUI_Command* XGUI_MenuGroupPanel::feature(const QString& theId) const if ((*aIt)->id() == theId) return (*aIt); return 0; -} \ No newline at end of file +} diff --git a/src/XGUI/XGUI_MenuGroupPanel.h b/src/XGUI/XGUI_MenuGroupPanel.h index a13981326..b43ef75c6 100644 --- a/src/XGUI/XGUI_MenuGroupPanel.h +++ b/src/XGUI/XGUI_MenuGroupPanel.h @@ -20,7 +20,8 @@ public: //! Adding a new feature (Command) in the group XGUI_Command* addFeature(const QString& theId, const QString& theTitle, const QString& theTip, - const QIcon& theIcon, const QKeySequence& theKeys = QKeySequence()); + const QIcon& theIcon, const QKeySequence& theKeys = QKeySequence(), + bool isCheckable = false); //! Returns already created command by its ID XGUI_Command* feature(const QString& theId) const; diff --git a/src/XGUI/XGUI_Workshop.cpp b/src/XGUI/XGUI_Workshop.cpp index 48e3770ce..cc6e63875 100644 --- a/src/XGUI/XGUI_Workshop.cpp +++ b/src/XGUI/XGUI_Workshop.cpp @@ -191,14 +191,16 @@ void XGUI_Workshop::addFeature(const Config_FeatureMessage* theMessage) if (!aGroup) { aGroup = aPage->addGroup(aGroupName); } + bool isUsePropPanel = theMessage->isUseInput(); //Create feature... - QString aFeatureId = QString::fromStdString(theMessage->id()); XGUI_Command* aCommand = aGroup->addFeature(QString::fromStdString(theMessage->id()), QString::fromStdString(theMessage->text()), QString::fromStdString(theMessage->tooltip()), - QIcon(theMessage->icon().c_str()) - //TODO(sbh): QKeySequence - ); + QIcon(theMessage->icon().c_str()), + QKeySequence(), isUsePropPanel); + + connect(aCommand, SIGNAL(toggled(bool)), + myMainWindow->menuObject(), SLOT(onFeatureChecked(bool))); myPartSetModule->featureCreated(aCommand); } @@ -207,7 +209,7 @@ void XGUI_Workshop::addFeature(const Config_FeatureMessage* theMessage) */ void XGUI_Workshop::fillPropertyPanel(ModuleBase_PropPanelOperation* theOperation) { - connectToPropertyPanel(theOperation); + connectWithOperation(theOperation); QWidget* aPropWidget = myMainWindow->findChild(XGUI::PROP_PANEL_WDG); qDeleteAll(aPropWidget->children()); theOperation->start(); @@ -234,7 +236,7 @@ void XGUI_Workshop::setCurrentOperation(ModuleBase_Operation* theOperation) * and given operation. The given operation becomes a * current operation and previous operation if exists */ -void XGUI_Workshop::connectToPropertyPanel(ModuleBase_Operation* theOperation) +void XGUI_Workshop::connectWithOperation(ModuleBase_Operation* theOperation) { QDockWidget* aPanel = myMainWindow->findChild(XGUI::PROP_PANEL); QPushButton* aOkBtn = aPanel->findChild(XGUI::PROP_PANEL_OK); @@ -245,6 +247,14 @@ void XGUI_Workshop::connectToPropertyPanel(ModuleBase_Operation* theOperation) connect(theOperation, SIGNAL(started()), myMainWindow, SLOT(showPropertyPanel())); connect(theOperation, SIGNAL(stopped()), myMainWindow, SLOT(hidePropertyPanel())); connect(theOperation, SIGNAL(stopped()), this, SLOT(updateCommandStatus())); + + XGUI_MainMenu* aMenu = myMainWindow->menuObject(); + connect(theOperation, SIGNAL(stopped()), aMenu, SLOT(restoreCommandState())); + + XGUI_Command* aCommand = aMenu->feature(theOperation->operationId()); + //Abort operation on uncheck the command + connect(aCommand, SIGNAL(toggled(bool)), theOperation, SLOT(setRunning(bool))); + } //****************************************************** @@ -309,7 +319,6 @@ void XGUI_Workshop::onRedo() updateCommandStatus(); } - //****************************************************** XGUI_Module* XGUI_Workshop::loadModule(const QString& theModule) { diff --git a/src/XGUI/XGUI_Workshop.h b/src/XGUI/XGUI_Workshop.h index aff5c239b..e0da52712 100644 --- a/src/XGUI/XGUI_Workshop.h +++ b/src/XGUI/XGUI_Workshop.h @@ -65,7 +65,7 @@ protected: //Event-loop processing methods: void addFeature(const Config_FeatureMessage*); void fillPropertyPanel(ModuleBase_PropPanelOperation* theOperation); - void connectToPropertyPanel(ModuleBase_Operation* theOperation); + void connectWithOperation(ModuleBase_Operation* theOperation); void setCurrentOperation(ModuleBase_Operation* theOperation); private: