From 60dfa3359d9982f72d6359fede8520280bfaa6db Mon Sep 17 00:00:00 2001 From: nds Date: Fri, 11 Sep 2015 11:22:19 +0300 Subject: [PATCH] Update error manager processing. --- src/ModuleBase/ModuleBase_IModule.cpp | 37 ++++++++++++++ src/ModuleBase/ModuleBase_IModule.h | 5 ++ src/NewGeom/NewGeom_Module.cpp | 8 +-- src/NewGeom/NewGeom_Module.h | 4 +- src/PartSet/PartSet_Module.cpp | 41 ++++++++++++++++ src/PartSet/PartSet_Module.h | 5 ++ src/PartSet/PartSet_SketcherMgr.cpp | 29 +++++++++++ src/PartSet/PartSet_SketcherMgr.h | 7 +++ src/SketchSolver/SketchSolver_Group.cpp | 9 ++-- src/XGUI/XGUI_ErrorMgr.cpp | 65 +++++++++++++++++++------ src/XGUI/XGUI_ErrorMgr.h | 22 ++++++--- src/XGUI/XGUI_OperationMgr.cpp | 45 +++++++++++++---- src/XGUI/XGUI_OperationMgr.h | 8 ++- src/XGUI/XGUI_SalomeConnector.h | 6 +-- src/XGUI/XGUI_Workshop.cpp | 28 +++++++++-- src/XGUI/XGUI_Workshop.h | 6 ++- src/XGUI/XGUI_WorkshopListener.cpp | 27 ++++++---- src/XGUI/XGUI_WorkshopListener.h | 2 +- 18 files changed, 290 insertions(+), 64 deletions(-) diff --git a/src/ModuleBase/ModuleBase_IModule.cpp b/src/ModuleBase/ModuleBase_IModule.cpp index 1dc47c098..0036afcad 100644 --- a/src/ModuleBase/ModuleBase_IModule.cpp +++ b/src/ModuleBase/ModuleBase_IModule.cpp @@ -64,6 +64,43 @@ void ModuleBase_IModule::sendOperation(ModuleBase_Operation* theOperation) Events_Loop::loop()->send(aMessage); } +const char* toString(ModelAPI_ExecState theExecState) +{ +#define TO_STRING(__NAME__) case __NAME__: return #__NAME__; + switch (theExecState) { + TO_STRING(ModelAPI_StateDone) + TO_STRING(ModelAPI_StateMustBeUpdated) + TO_STRING(ModelAPI_StateExecFailed) + TO_STRING(ModelAPI_StateInvalidArgument) + TO_STRING(ModelAPI_StateNothing) + default: return "Unknown ExecState."; + } +#undef TO_STRING +} + +QString ModuleBase_IModule::getFeatureError(const FeaturePtr& theFeature) +{ + QString anError; + if (!theFeature.get() || !theFeature->data()->isValid() || theFeature->isAction()) + return anError; + + // to be removed later, this error should be got from the feature + if (theFeature->data()->execState() == ModelAPI_StateDone || + theFeature->data()->execState() == ModelAPI_StateMustBeUpdated) + return anError; + + // set error indication + anError = QString::fromStdString(theFeature->error()); + if (anError.isEmpty()) { + bool isDone = ( theFeature->data()->execState() == ModelAPI_StateDone + || theFeature->data()->execState() == ModelAPI_StateMustBeUpdated ); + if (!isDone) + anError = toString(theFeature->data()->execState()); + } + + return anError; +} + ModuleBase_Operation* ModuleBase_IModule::getNewOperation(const std::string& theFeatureId) { return new ModuleBase_OperationFeature(theFeatureId.c_str(), this); diff --git a/src/ModuleBase/ModuleBase_IModule.h b/src/ModuleBase/ModuleBase_IModule.h index ea6124eb4..45b57d67f 100644 --- a/src/ModuleBase/ModuleBase_IModule.h +++ b/src/ModuleBase/ModuleBase_IModule.h @@ -194,6 +194,11 @@ class MODULEBASE_EXPORT ModuleBase_IModule : public QObject /// \param theStdActions - a map of standard actions virtual void updateViewerMenu(const QMap& theStdActions) {} + //! Returns the feature error if the current state of the feature in the module is not correct + //! If the feature is correct, it returns an empty value + //! \return string value + virtual QString getFeatureError(const FeaturePtr& theFeature); + signals: void operationLaunched(); diff --git a/src/NewGeom/NewGeom_Module.cpp b/src/NewGeom/NewGeom_Module.cpp index 79d725c64..17c0574e4 100644 --- a/src/NewGeom/NewGeom_Module.cpp +++ b/src/NewGeom/NewGeom_Module.cpp @@ -403,14 +403,14 @@ QAction* NewGeom_Module::addFeature(const QString& theWBName, const QString& the return aAction; } -bool NewGeom_Module::isNestedFeature(const QAction* theAction) +bool NewGeom_Module::isFeatureOfNested(const QAction* theAction) { return dynamic_cast(theAction); } -QAction* NewGeom_Module::addNestedFeature(const QString& theWBName, - const ActionInfo& theInfo, - const QList& theNestedActions) +QAction* NewGeom_Module::addFeatureOfNested(const QString& theWBName, + const ActionInfo& theInfo, + const QList& theNestedActions) { int aMenu = createMenu(theWBName, -1, -1, 50); int aTool = createTool(theWBName, theWBName); diff --git a/src/NewGeom/NewGeom_Module.h b/src/NewGeom/NewGeom_Module.h index 6024fa843..d537b8a8d 100644 --- a/src/NewGeom/NewGeom_Module.h +++ b/src/NewGeom/NewGeom_Module.h @@ -57,7 +57,7 @@ Q_OBJECT virtual QAction* addFeature(const QString& theWBName, const ActionInfo& theInfo); - virtual QAction* addNestedFeature(const QString& theWBName, + virtual QAction* addFeatureOfNested(const QString& theWBName, const ActionInfo& theInfo, const QList& theNestedActions); @@ -65,7 +65,7 @@ Q_OBJECT //! it is created by addNestedFeature(). //! \param theId - an action of a feature //! returns boolean result - virtual bool isNestedFeature(const QAction* theAction); + virtual bool isFeatureOfNested(const QAction* theAction); virtual QAction* addDesktopCommand(const QString& theId, const QString& theTitle, const QString& theTip, const QIcon& theIcon, diff --git a/src/PartSet/PartSet_Module.cpp b/src/PartSet/PartSet_Module.cpp index 1abaeb6b0..e0c4b568c 100755 --- a/src/PartSet/PartSet_Module.cpp +++ b/src/PartSet/PartSet_Module.cpp @@ -51,6 +51,7 @@ #include #include #include +#include #include #include @@ -66,6 +67,7 @@ #include #include #include +#include #include #include @@ -150,6 +152,8 @@ PartSet_Module::PartSet_Module(ModuleBase_IWorkshop* theWshop) Events_Loop* aLoop = Events_Loop::loop(); aLoop->registerListener(this, Events_Loop::eventByName(EVENT_DOCUMENT_CHANGED)); + aLoop->registerListener(this, Events_Loop::eventByName(EVENT_SOLVER_FAILED)); + aLoop->registerListener(this, Events_Loop::eventByName(EVENT_SOLVER_REPAIRED)); mySelectionFilters.Append(new PartSet_GlobalFilter(myWorkshop)); mySelectionFilters.Append(new PartSet_FilterInfinite(myWorkshop)); @@ -412,6 +416,26 @@ void PartSet_Module::updateViewerMenu(const QMap& theStdActio myMenuMgr->updateViewerMenu(theStdActions); } +QString PartSet_Module::getFeatureError(const FeaturePtr& theFeature) +{ + QString anError = ModuleBase_IModule::getFeatureError(theFeature); + + if (anError.isEmpty()) + anError = sketchMgr()->getFeatureError(theFeature); + + if (anError.isEmpty()) { + XGUI_ModuleConnector* aConnector = dynamic_cast(workshop()); + XGUI_OperationMgr* anOpMgr = aConnector->workshop()->operationMgr(); + + if (anOpMgr->isValidationLocked()) { + ModuleBase_OperationFeature* aFOperation = dynamic_cast + (anOpMgr->currentOperation()); + if (!aFOperation || theFeature == aFOperation->feature()) + anError = "Validation is locked by the current operation"; + } + } + return anError; +} void PartSet_Module::activeSelectionModes(QIntList& theModes) { @@ -995,6 +1019,23 @@ void PartSet_Module::processEvent(const std::shared_ptr& theMess foreach(ObjectPtr aObj, aObjects) aDisplayer->redisplay(aObj, false); aDisplayer->updateViewer(); + } else if (theMessage->eventID() == Events_Loop::eventByName(EVENT_SOLVER_FAILED) || + theMessage->eventID() == Events_Loop::eventByName(EVENT_SOLVER_REPAIRED)) { + CompositeFeaturePtr aSketch = sketchMgr()->activeSketch(); + if (aSketch.get()) { + if (theMessage->eventID() == Events_Loop::eventByName(EVENT_SOLVER_REPAIRED)) { + // it should be moved out, validating is called to update error string of the sketch feature + if (sketchMgr()->activeSketch().get()) { + SessionPtr aMgr = ModelAPI_Session::get(); + ModelAPI_ValidatorsFactory* aFactory = aMgr->validators(); + bool aValid = aFactory->validate(sketchMgr()->activeSketch()); + } + } + + XGUI_ModuleConnector* aConnector = dynamic_cast(workshop()); + XGUI_Workshop* aWorkshop = aConnector->workshop(); + aWorkshop->errorMgr()->updateActions(aSketch); + } } } diff --git a/src/PartSet/PartSet_Module.h b/src/PartSet/PartSet_Module.h index bdcbdd0ec..9746f4356 100644 --- a/src/PartSet/PartSet_Module.h +++ b/src/PartSet/PartSet_Module.h @@ -199,6 +199,11 @@ public: /// \param theStdActions - a map of standard actions virtual void updateViewerMenu(const QMap& theStdActions); + //! Returns the feature error if the current state of the feature in the module is not correct + //! If the feature is correct, it returns an empty value + //! \return string value + virtual QString getFeatureError(const FeaturePtr& theFeature); + public slots: /// SLOT, that is called by no more widget signal emitted by property panel /// Set a specific flag to restart the sketcher operation diff --git a/src/PartSet/PartSet_SketcherMgr.cpp b/src/PartSet/PartSet_SketcherMgr.cpp index ae2181836..31201593e 100644 --- a/src/PartSet/PartSet_SketcherMgr.cpp +++ b/src/PartSet/PartSet_SketcherMgr.cpp @@ -678,6 +678,35 @@ bool PartSet_SketcherMgr::sketchSolverError() return anError; } +QString PartSet_SketcherMgr::getFeatureError(const FeaturePtr& theFeature) +{ + QString anError = ""; + if (!theFeature.get() || !theFeature->data()->isValid()) + return anError; + + CompositeFeaturePtr aSketch = activeSketch(); + if (aSketch.get() && aSketch == theFeature) { + AttributeStringPtr aAttributeString = aSketch->string(SketchPlugin_Sketch::SOLVER_ERROR()); + anError = aAttributeString->value().c_str(); + if (anError.isEmpty()) { + if (isNestedCreateOperation(getCurrentOperation()) && + aSketch->numberOfSubs() == 1) { + AttributePtr aFeaturesAttr = aSketch->attribute(SketchPlugin_Sketch::FEATURES_ID()); + anError = std::string("Attribute \"" + aFeaturesAttr->id() + "\" is not initialized.").c_str(); + } + } + } + else if (myIsResetCurrentValue) { // this flag do not allow commit of the current operation + ModuleBase_OperationFeature* aFOperation = dynamic_cast + (getCurrentOperation()); + if (aFOperation) { + FeaturePtr aFeature = aFOperation->feature(); + if (aFeature.get() && aFeature == theFeature && isNestedCreateOperation(aFOperation)) + anError = "Please input value in Property Panel. It is not initialized."; + } + } + return anError; +} const QStringList& PartSet_SketcherMgr::sketchOperationIdList() { diff --git a/src/PartSet/PartSet_SketcherMgr.h b/src/PartSet/PartSet_SketcherMgr.h index 08a152236..8344edf2b 100644 --- a/src/PartSet/PartSet_SketcherMgr.h +++ b/src/PartSet/PartSet_SketcherMgr.h @@ -174,6 +174,13 @@ public: /// \return boolean value bool sketchSolverError(); + //! Returns the feature error if the current state of the feature in the sketch is not correct + //! If the feature is correct, it returns an empty value + //! Incorrect states: the feature is sketch, the solver error value + //! The feature value is reset, this is the flag of sketch mgr + //! \return string value + QString getFeatureError(const FeaturePtr& theFeature); + /// Returns list of strings which contains id's of sketch operations static const QStringList& sketchOperationIdList(); diff --git a/src/SketchSolver/SketchSolver_Group.cpp b/src/SketchSolver/SketchSolver_Group.cpp index 5bce44595..0e4093ffa 100644 --- a/src/SketchSolver/SketchSolver_Group.cpp +++ b/src/SketchSolver/SketchSolver_Group.cpp @@ -505,11 +505,12 @@ bool SketchSolver_Group::resolveConstraints() } } catch (...) { // Events_Error::send(SketchSolver_Error::SOLVESPACE_CRASH(), this); + getWorkplane()->string(SketchPlugin_Sketch::SOLVER_ERROR())->setValue(SketchSolver_Error::SOLVESPACE_CRASH()); if (myPrevSolved) { + // the error message should be changed before sending the message sendMessage(EVENT_SOLVER_FAILED); myPrevSolved = false; } - getWorkplane()->string(SketchPlugin_Sketch::SOLVER_ERROR())->setValue(SketchSolver_Error::SOLVESPACE_CRASH()); return false; } if (aResult == SLVS_RESULT_OKAY) { // solution succeeded, store results into correspondent attributes @@ -519,17 +520,19 @@ bool SketchSolver_Group::resolveConstraints() aConstrIter->second->refresh(); myFeatureStorage->blockEvents(false); if (!myPrevSolved) { + getWorkplane()->string(SketchPlugin_Sketch::SOLVER_ERROR())->setValue(""); + // the error message should be changed before sending the message sendMessage(EVENT_SOLVER_REPAIRED); myPrevSolved = true; - getWorkplane()->string(SketchPlugin_Sketch::SOLVER_ERROR())->setValue(""); } } else if (!myConstraints.empty()) { // Events_Error::send(SketchSolver_Error::CONSTRAINTS(), this); + getWorkplane()->string(SketchPlugin_Sketch::SOLVER_ERROR())->setValue(SketchSolver_Error::CONSTRAINTS()); if (myPrevSolved) { + // the error message should be changed before sending the message sendMessage(EVENT_SOLVER_FAILED); myPrevSolved = false; } - getWorkplane()->string(SketchPlugin_Sketch::SOLVER_ERROR())->setValue(SketchSolver_Error::CONSTRAINTS()); } aResolved = true; diff --git a/src/XGUI/XGUI_ErrorMgr.cpp b/src/XGUI/XGUI_ErrorMgr.cpp index 8a92c1d62..355c8d9a1 100644 --- a/src/XGUI/XGUI_ErrorMgr.cpp +++ b/src/XGUI/XGUI_ErrorMgr.cpp @@ -7,8 +7,13 @@ #include "XGUI_ErrorMgr.h" #include "XGUI_OperationMgr.h" +#include "XGUI_ModuleConnector.h" +#include "XGUI_Workshop.h" +#include "XGUI_ActionsMgr.h" #include +#include +#include #include #include @@ -28,10 +33,11 @@ const QString INVALID_VALUE = "invalid_action"; -XGUI_ErrorMgr::XGUI_ErrorMgr(QObject* theParent /*= 0*/) +XGUI_ErrorMgr::XGUI_ErrorMgr(QObject* theParent, ModuleBase_IWorkshop* theWorkshop) : ModuleBase_IErrorMgr(theParent), myErrorDialog(0), - myErrorLabel(0) + myErrorLabel(0), + myWorkshop(theWorkshop) { } @@ -41,13 +47,31 @@ XGUI_ErrorMgr::~XGUI_ErrorMgr() } -bool XGUI_ErrorMgr::canProcessClick(QAction* theAction, const FeaturePtr& theFeature) +void XGUI_ErrorMgr::updateActions(const FeaturePtr& theFeature) { - QString aData = theAction->data().toString(); + QString anError = myWorkshop->module()->getFeatureError(theFeature); - bool isActionEnabled = theAction->data() != INVALID_VALUE; + //update Ok Action and header of property panel if the current operation started for the feature + XGUI_ActionsMgr* anActionsMgr = workshop()->actionsMgr(); + ModuleBase_OperationFeature* aFOperation = dynamic_cast + (workshop()->operationMgr()->currentOperation()); + if (aFOperation && aFOperation->feature() == theFeature) { + QAction* anOkAction = anActionsMgr->operationStateAction(XGUI_ActionsMgr::Accept); + updateActionState(anOkAction, theFeature); + } + //update AcceptAll action + if (workshop()->isFeatureOfNested(theFeature)) { + QAction* anAcceptAllAction = anActionsMgr->operationStateAction(XGUI_ActionsMgr::AcceptAll, NULL); + bool anEnabled = anError.isEmpty(); + anAcceptAllAction->setEnabled(anEnabled); + anAcceptAllAction->setToolTip(anError); + } +} - QString anError = getFeatureError(theFeature); +bool XGUI_ErrorMgr::canProcessClick(QAction* theAction, const FeaturePtr& theFeature) +{ + QString anError = myWorkshop->module()->getFeatureError(theFeature); + bool isActionEnabled = anError.isEmpty(); if (!isActionEnabled && !anError.isEmpty()) { if (!myErrorDialog) { myErrorDialog = new QDialog(QApplication::desktop(), Qt::Popup); @@ -71,14 +95,17 @@ bool XGUI_ErrorMgr::canProcessClick(QAction* theAction, const FeaturePtr& theFea return isActionEnabled; } -void XGUI_ErrorMgr::updateActionState(QAction* theAction, const FeaturePtr& theFeature, - const bool theEnabled) +void XGUI_ErrorMgr::updateActionState(QAction* theAction, const FeaturePtr& theFeature/*, + const bool theEnabled*/) { + QString anError = myWorkshop->module()->getFeatureError(theFeature); + bool anEnabled = anError.isEmpty(); + bool isActionEnabled = theAction->data() != INVALID_VALUE; - if (theEnabled != isActionEnabled) { + if (anEnabled != isActionEnabled) { // update enable state of the button - theAction->setIcon(theEnabled ? QIcon(":pictures/button_ok.png"): QIcon(":pictures/button_ok_error.png")); - if (theEnabled) + theAction->setIcon(anEnabled ? QIcon(":pictures/button_ok.png"): QIcon(":pictures/button_ok_error.png")); + if (anEnabled) theAction->setData(""); else theAction->setData(INVALID_VALUE); @@ -88,11 +115,11 @@ void XGUI_ErrorMgr::updateActionState(QAction* theAction, const FeaturePtr& theF // update controls error information QWidget* aWidget = myPropertyPanel->headerWidget(); if (aWidget) - aWidget->setToolTip(getFeatureError(theFeature)); + aWidget->setToolTip(anError); } } -const char* toString(ModelAPI_ExecState theExecState) +/*const char* toString(ModelAPI_ExecState theExecState) { #define TO_STRING(__NAME__) case __NAME__: return #__NAME__; switch (theExecState) { @@ -104,7 +131,7 @@ const char* toString(ModelAPI_ExecState theExecState) default: return "Unknown ExecState."; } #undef TO_STRING -} +}*/ /*void XGUI_ErrorMgr::onValidationStateChanged() { @@ -126,7 +153,7 @@ const char* toString(ModelAPI_ExecState theExecState) } }*/ -QString XGUI_ErrorMgr::getFeatureError(const FeaturePtr& theFeature) const +/*QString XGUI_ErrorMgr::getFeatureError(const FeaturePtr& theFeature) const { QString anError; // get feature @@ -143,7 +170,7 @@ QString XGUI_ErrorMgr::getFeatureError(const FeaturePtr& theFeature) const } return anError; -} +}*/ void XGUI_ErrorMgr::onWidgetChanged() { @@ -185,3 +212,9 @@ void XGUI_ErrorMgr::onWidgetChanged() //aWidget->setStyleSheet(anError.isEmpty() ? "" : "background-color:pink;"); } } + +XGUI_Workshop* XGUI_ErrorMgr::workshop() const +{ + XGUI_ModuleConnector* aConnector = dynamic_cast(myWorkshop); + return aConnector->workshop(); +} diff --git a/src/XGUI/XGUI_ErrorMgr.h b/src/XGUI/XGUI_ErrorMgr.h index b370da0b7..656b2ca3a 100644 --- a/src/XGUI/XGUI_ErrorMgr.h +++ b/src/XGUI/XGUI_ErrorMgr.h @@ -12,6 +12,8 @@ #include #include +class XGUI_Workshop; +class ModuleBase_IWorkshop; class QAction; class QDialog; class QLabel; @@ -20,16 +22,11 @@ class XGUI_EXPORT XGUI_ErrorMgr : public ModuleBase_IErrorMgr { Q_OBJECT public: - XGUI_ErrorMgr(QObject* theParent = 0); + XGUI_ErrorMgr(QObject* theParent, ModuleBase_IWorkshop* theWorkshop); /// Virtual destructor virtual ~XGUI_ErrorMgr(); - /// It updates the action state according to the given parameter - /// \param theAction an action to be changed - /// \param theFeature an feature that corresponds to the action - /// \param theEnabled an enable state - void updateActionState(QAction* theAction, const FeaturePtr& theFeature, - const bool theEnabled); + void updateActions(const FeaturePtr& theFeature); /// Return true if the feature has no error. If there is an error and the action /// is not valid, the dialog with the error information is shown. @@ -46,12 +43,21 @@ protected slots: virtual void onWidgetChanged(); private: + /// It updates the action state according to the given parameter + /// \param theAction an action to be changed + /// \param theFeature an feature that corresponds to the action + void updateActionState(QAction* theAction, const FeaturePtr& theFeature); + /// Returns the feature error message /// \param theFeature a feature /// \return the error message - QString getFeatureError(const FeaturePtr& theFeature) const; + //QString getFeatureError(const FeaturePtr& theFeature) const; + + /// Returns casted workshop + XGUI_Workshop* workshop() const; private: + ModuleBase_IWorkshop* myWorkshop; QDialog* myErrorDialog; /// contains the error message QLabel* myErrorLabel; /// contains an error information }; diff --git a/src/XGUI/XGUI_OperationMgr.cpp b/src/XGUI/XGUI_OperationMgr.cpp index efc2ce9d5..033e1d44c 100644 --- a/src/XGUI/XGUI_OperationMgr.cpp +++ b/src/XGUI/XGUI_OperationMgr.cpp @@ -5,6 +5,9 @@ // Author: Natalia ERMOLAEVA #include "XGUI_OperationMgr.h" +#include "XGUI_ModuleConnector.h" +#include "XGUI_Workshop.h" +#include "XGUI_ErrorMgr.h" #include "ModuleBase_Operation.h" #include "ModuleBase_IWorkshop.h" @@ -184,10 +187,13 @@ void XGUI_OperationMgr::onValidateOperation() { if (!hasOperation()) return; - ModuleBase_Operation* anOperation = currentOperation(); - if(anOperation) { - bool aCanCommit = myWorkshop->module()->canCommitOperation(); - setApplyEnabled(!myIsValidationLock && aCanCommit && anOperation->isValid()); + //ModuleBase_Operation* anOperation = currentOperation(); + ModuleBase_OperationFeature* aFOperation = dynamic_cast + (currentOperation()); + if(aFOperation && aFOperation->feature().get()) { + //bool aCanCommit = myWorkshop->module()->canCommitOperation(); + //setApplyEnabled(!myIsValidationLock && aCanCommit && anOperation->isValid()); + setApplyEnabled(myWorkshop->module()->getFeatureError(aFOperation->feature()).isEmpty()); } } @@ -200,18 +206,30 @@ void XGUI_OperationMgr::setLockValidating(bool toLock) void XGUI_OperationMgr::setApplyEnabled(const bool theEnabled) { myIsApplyEnabled = theEnabled; - emit validationStateChanged(theEnabled); + ModuleBase_OperationFeature* aFOperation = dynamic_cast + (currentOperation()); + if (aFOperation) { + workshop()->errorMgr()->updateActions(aFOperation->feature()); + } + //emit validationStateChanged(theEnabled); } void XGUI_OperationMgr::updateApplyOfOperations(ModuleBase_Operation* theOperation) { - if (theOperation) - emit nestedStateChanged(theOperation->getDescription()->operationId().toStdString(), - theOperation->isValid()); + XGUI_ErrorMgr* anErrorMgr = workshop()->errorMgr(); + if (theOperation) { + ModuleBase_OperationFeature* aFOperation = dynamic_cast(theOperation); + if (aFOperation) + anErrorMgr->updateActions(aFOperation->feature()); + //emit nestedStateChanged(theOperation->getDescription()->operationId().toStdString(), + // theOperation->isValid()); + } else { foreach(ModuleBase_Operation* anOperation, myOperations) { - emit nestedStateChanged(anOperation->getDescription()->operationId().toStdString(), - anOperation->isValid()); + if (anOperation) + updateApplyOfOperations(anOperation); + //emit nestedStateChanged(anOperation->getDescription()->operationId().toStdString(), + // anOperation->isValid()); } } } @@ -359,6 +377,7 @@ void XGUI_OperationMgr::onOperationAborted() void XGUI_OperationMgr::onOperationCommitted() { + // apply state for all features from the stack of operations should be updated updateApplyOfOperations(); ModuleBase_Operation* aSenderOperation = dynamic_cast(sender()); @@ -438,3 +457,9 @@ bool XGUI_OperationMgr::onKeyReleased(QKeyEvent* theEvent) return isAccepted; } +XGUI_Workshop* XGUI_OperationMgr::workshop() const +{ + XGUI_ModuleConnector* aConnector = dynamic_cast(myWorkshop); + return aConnector->workshop(); +} + diff --git a/src/XGUI/XGUI_OperationMgr.h b/src/XGUI/XGUI_OperationMgr.h index bfb9fdace..3cd0f9a37 100644 --- a/src/XGUI/XGUI_OperationMgr.h +++ b/src/XGUI/XGUI_OperationMgr.h @@ -18,6 +18,7 @@ class QKeyEvent; class ModuleBase_IWorkshop; +class XGUI_Workshop; /**\class XGUI_OperationMgr * \ingroup GUI @@ -139,12 +140,12 @@ signals: void operationAborted(ModuleBase_Operation* theOperation); /// Signal is emitted after the apply enable state changed. - void validationStateChanged(bool); + //void validationStateChanged(bool); /// Signal is emitted after the model is modified. It is emitted for all active operations. /// \param theFeatureKind a feature id /// \param theState validity of the operation with the feature kind - void nestedStateChanged(const std::string& theFeatureKind, const bool theState); + //void nestedStateChanged(const std::string& theFeatureKind, const bool theState); /// Signal is emitted after the current operation is filled with existing preselection. void operationActivatedByPreselection(); @@ -199,6 +200,9 @@ protected: // TEMPORARY /// Slot called on operation resume void onOperationResumed(); +private: + XGUI_Workshop* workshop() const; + private: typedef QList Operations; ///< definition for a list of operations Operations myOperations; ///< a stack of started operations. The active operation is on top, diff --git a/src/XGUI/XGUI_SalomeConnector.h b/src/XGUI/XGUI_SalomeConnector.h index 910aaa249..807e1868f 100644 --- a/src/XGUI/XGUI_SalomeConnector.h +++ b/src/XGUI/XGUI_SalomeConnector.h @@ -48,15 +48,15 @@ class XGUI_EXPORT XGUI_SalomeConnector //! Creates a feature (command) in SALOME desktop //! \param theWBName - name of toolbar (workbench) //! \param theInfo - information about action (icon, text, etc) - virtual QAction* addNestedFeature(const QString& theWBName, + virtual QAction* addFeatureOfNested(const QString& theWBName, const ActionInfo& theInfo, const QList& theNestedActions) = 0; //! Returns true if the feature action is a nested action, in other words, - //! it is created by addNestedFeature(). + //! it is created by addFeatureOfNested(). //! \param theId - an action of a feature //! returns boolean result - virtual bool isNestedFeature(const QAction* theAction) = 0; + virtual bool isFeatureOfNested(const QAction* theAction) = 0; //! Creates a command in Edit menu of SALOME desktop //! \param theId - an id of the feature diff --git a/src/XGUI/XGUI_Workshop.cpp b/src/XGUI/XGUI_Workshop.cpp index 2eed6244b..533efe7bf 100644 --- a/src/XGUI/XGUI_Workshop.cpp +++ b/src/XGUI/XGUI_Workshop.cpp @@ -131,7 +131,6 @@ XGUI_Workshop::XGUI_Workshop(XGUI_SalomeConnector* theConnector) myOperationMgr = new XGUI_OperationMgr(this, 0); myActionsMgr = new XGUI_ActionsMgr(this); myErrorDlg = new XGUI_ErrorDialog(QApplication::desktop()); - myErrorMgr = new XGUI_ErrorMgr(this); myContextMenuMgr = new XGUI_ContextMenuMgr(this); connect(myContextMenuMgr, SIGNAL(actionTriggered(const QString&, bool)), this, SLOT(onContextMenuCommand(const QString&, bool))); @@ -145,6 +144,7 @@ XGUI_Workshop::XGUI_Workshop(XGUI_SalomeConnector* theConnector) ModuleBase_IWorkshop* aWorkshop = moduleConnector(); myOperationMgr->setWorkshop(aWorkshop); + myErrorMgr = new XGUI_ErrorMgr(this, aWorkshop); myEventsListener = new XGUI_WorkshopListener(aWorkshop); connect(myOperationMgr, SIGNAL(operationStarted(ModuleBase_Operation*)), @@ -392,7 +392,7 @@ void XGUI_Workshop::onAcceptActionClicked() } //****************************************************** -void XGUI_Workshop::onValidationStateChanged(bool theEnabled) +/*void XGUI_Workshop::onValidationStateChanged(bool theEnabled) { XGUI_OperationMgr* anOperationMgr = operationMgr(); if (anOperationMgr) { @@ -403,7 +403,7 @@ void XGUI_Workshop::onValidationStateChanged(bool theEnabled) myErrorMgr->updateActionState(anAction, aFOperation->feature(), theEnabled); } } -} +}*/ //****************************************************** @@ -418,6 +418,24 @@ void XGUI_Workshop::deactivateActiveObject(const ObjectPtr& theObject, const boo } } +//****************************************************** +bool XGUI_Workshop::isFeatureOfNested(const FeaturePtr& theFeature) +{ + bool aHasNested = false; + std::string aFeatureKind = theFeature->getKind(); + if (isSalomeMode()) { + XGUI_SalomeConnector* aSalomeConnector = salomeConnector(); + if (aSalomeConnector->isFeatureOfNested(actionsMgr()->action(aFeatureKind.c_str()))) + aHasNested = true; + } else { + AppElements_MainMenu* aMenuBar = mainWindow()->menuObject(); + AppElements_Command* aCommand = aMenuBar->feature(aFeatureKind.c_str()); + if (aCommand && aCommand->button()->additionalButtonWidget()) + aHasNested = true; + } + return aHasNested; +} + //****************************************************** void XGUI_Workshop::onOperationStarted(ModuleBase_Operation* theOperation) { @@ -979,8 +997,8 @@ void XGUI_Workshop::createDockWidgets() connect(myPropertyPanel, SIGNAL(noMoreWidgets()), myModule, SLOT(onNoMoreWidgets())); connect(myPropertyPanel, SIGNAL(keyReleased(QKeyEvent*)), myOperationMgr, SLOT(onKeyReleased(QKeyEvent*))); - connect(myOperationMgr, SIGNAL(validationStateChanged(bool)), - this, SLOT(onValidationStateChanged(bool))); + //connect(myOperationMgr, SIGNAL(validationStateChanged(bool)), + // this, SLOT(onValidationStateChanged(bool))); } //****************************************************** diff --git a/src/XGUI/XGUI_Workshop.h b/src/XGUI/XGUI_Workshop.h index 4c8b51c1f..cddb72f72 100644 --- a/src/XGUI/XGUI_Workshop.h +++ b/src/XGUI/XGUI_Workshop.h @@ -241,6 +241,10 @@ Q_OBJECT /// \param theUpdateViewer a boolean flag to update viewer immediately void deactivateActiveObject(const ObjectPtr& theObject, const bool theUpdateViewer); + /// Returns true if the action of the feature is created to contain Accept/Cancel button + /// \param theFeature a feature + bool isFeatureOfNested(const FeaturePtr& theFeature); + signals: /// Emitted when selection happens in Salome viewer void salomeViewerSelection(); @@ -370,7 +374,7 @@ private: /// Listens the corresponded signal from operation manager and send it with the Ok /// action to operation manager. /// \param theEnabled an enabled state for the action - void onValidationStateChanged(bool theEnabled); + //void onValidationStateChanged(bool theEnabled); //connect(myOperationMgr, SIGNAL(validationStateChanged(bool)), // aOkAct, SLOT(setEnabled(bool))); diff --git a/src/XGUI/XGUI_WorkshopListener.cpp b/src/XGUI/XGUI_WorkshopListener.cpp index ef3c66d55..570ebbf23 100755 --- a/src/XGUI/XGUI_WorkshopListener.cpp +++ b/src/XGUI/XGUI_WorkshopListener.cpp @@ -68,8 +68,8 @@ XGUI_WorkshopListener::XGUI_WorkshopListener(ModuleBase_IWorkshop* theWorkshop) myUpdatePrefs(false) { XGUI_OperationMgr* anOperationMgr = workshop()->operationMgr(); - connect(anOperationMgr, SIGNAL(nestedStateChanged(const std::string&, const bool)), - this, SLOT(onNestedStateChanged(const std::string&, const bool))); + //connect(anOperationMgr, SIGNAL(nestedStateChanged(const std::string&, const bool)), + // this, SLOT(onNestedStateChanged(const std::string&, const bool))); } //****************************************************** @@ -91,6 +91,7 @@ void XGUI_WorkshopListener::initializeEventListening() aLoop->registerListener(this, Events_LongOp::eventID()); aLoop->registerListener(this, Events_Loop::eventByName(EVENT_PLUGIN_LOADED)); aLoop->registerListener(this, Events_Loop::eventByName(EVENT_SELFILTER_LOADED)); + aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_ERROR_CHANGED)); aLoop->registerListener(this, Events_Loop::eventByName(EVENT_UPDATE_VIEWER_BLOCKED)); aLoop->registerListener(this, Events_Loop::eventByName(EVENT_UPDATE_VIEWER_UNBLOCKED)); @@ -187,6 +188,14 @@ void XGUI_WorkshopListener::processEvent(const std::shared_ptr& XGUI_Displayer* aDisplayer = workshop()->displayer(); aDisplayer->enableUpdateViewer(true); aDisplayer->updateViewer(); + } else if (theMessage->eventID() == Events_Loop::eventByName(EVENT_OBJECT_ERROR_CHANGED)) { + std::shared_ptr aUpdMsg = + std::dynamic_pointer_cast(theMessage); + std::set aObjects = aUpdMsg->objects(); + std::set::const_iterator aIt; + for (aIt = aObjects.begin(); aIt != aObjects.end(); ++aIt) { + workshop()->errorMgr()->updateActions(ModelAPI_Feature::feature(*aIt)); + } } else { //Show error dialog if error message received. std::shared_ptr anAppError = std::dynamic_pointer_cast(theMessage); @@ -234,7 +243,7 @@ void XGUI_WorkshopListener::onFeatureUpdatedMsg( } } } - anOperationMgr->onValidateOperation(); + //anOperationMgr->onValidateOperation(); //if (myObjectBrowser) // myObjectBrowser->processEvent(theMsg); @@ -388,18 +397,17 @@ void XGUI_WorkshopListener::onFeatureCreatedMsg(const std::shared_ptractionsMgr()->operationStateAction(XGUI_ActionsMgr::AcceptAll, NULL); - bool aActionToBeUpdated = false; + //bool aActionToBeUpdated = aWorkshop->isFeatureOfNested(theFeatureId); if (aWorkshop->isSalomeMode()) { XGUI_SalomeConnector* aSalomeConnector = aWorkshop->salomeConnector(); XGUI_ActionsMgr* anActionsMgr = aWorkshop->actionsMgr(); - if (aSalomeConnector->isNestedFeature(anActionsMgr->action(theFeatureId.c_str()))) + if (aSalomeConnector->isFeatureOfNested(anActionsMgr->action(theFeatureId.c_str()))) aActionToBeUpdated = true; } else { AppElements_MainMenu* aMenuBar = aWorkshop->mainWindow()->menuObject(); @@ -408,9 +416,10 @@ void XGUI_WorkshopListener::onNestedStateChanged(const std::string& theFeatureId aActionToBeUpdated = true; } if (aActionToBeUpdated) { + QAction* anAcceptAllAction = aWorkshop->actionsMgr()->operationStateAction(XGUI_ActionsMgr::AcceptAll, NULL); anAcceptAllAction->setEnabled(theState); } -} +}*/ bool XGUI_WorkshopListener::event(QEvent * theEvent) { @@ -462,7 +471,7 @@ void XGUI_WorkshopListener::addFeature(const std::shared_ptrsalomeConnector(); QAction* aAction; if (isColumnButton) { - aAction = aSalomeConnector->addNestedFeature(aWchName, aFeatureInfo, aNestedActList); + aAction = aSalomeConnector->addFeatureOfNested(aWchName, aFeatureInfo, aNestedActList); } else { //Issue #650: in the SALOME mode the tooltip should be same as text aFeatureInfo.toolTip = aFeatureInfo.text; diff --git a/src/XGUI/XGUI_WorkshopListener.h b/src/XGUI/XGUI_WorkshopListener.h index fa41577cc..16a0de871 100755 --- a/src/XGUI/XGUI_WorkshopListener.h +++ b/src/XGUI/XGUI_WorkshopListener.h @@ -48,7 +48,7 @@ protected slots: /// Updates Apply All button state of the feature to the state if the feature has the button /// \param theFeatureId an index of the feature, the action is searched, which state is to be changed /// \param theState an action enable state - void onNestedStateChanged(const std::string& theFeatureId, const bool theState); + //void onNestedStateChanged(const std::string& theFeatureId, const bool theState); protected: /// Procedure to process postponed events -- 2.39.2