From 47c024e673a2da5094f8f233124c412d0fcdc9b4 Mon Sep 17 00:00:00 2001 From: sbh Date: Fri, 12 Dec 2014 18:35:00 +0300 Subject: [PATCH] Ability for plugins to manage state (on/off) of their features added --- src/Model/Model_Session.cpp | 8 + src/Model/Model_Validator.cpp | 6 +- src/Model/Model_Validator.h | 3 +- src/ModelAPI/ModelAPI_Events.cpp | 50 ++++ src/ModelAPI/ModelAPI_Events.h | 28 +++ src/ModelAPI/ModelAPI_Plugin.h | 1 - src/ModuleBase/ModuleBase_Operation.cpp | 7 +- src/ModuleBase/ModuleBase_Operation.h | 5 - .../ModuleBase_SelectionValidator.h | 8 + src/PartSet/CMakeLists.txt | 2 - src/PartSet/PartSet_Module.cpp | 12 +- src/PartSet/PartSet_Module.h | 3 - src/PartSet/PartSet_OperationSketch.cpp | 56 ----- src/PartSet/PartSet_OperationSketch.h | 45 ---- src/PartSet/PartSet_Validators.cpp | 13 +- src/PartSet/PartSet_Validators.h | 7 + src/PartSetPlugin/CMakeLists.txt | 1 + src/PartSetPlugin/PartSetPlugin_Plugin.cpp | 35 +++ src/PartSetPlugin/PartSetPlugin_Plugin.h | 19 +- src/SketchPlugin/CMakeLists.txt | 1 + src/SketchPlugin/SketchPlugin_Plugin.cpp | 83 +++++-- src/SketchPlugin/SketchPlugin_Plugin.h | 19 +- src/SketchPlugin/plugin-Sketch.xml | 3 +- src/XGUI/XGUI_ActionsMgr.cpp | 230 ++++++++++++------ src/XGUI/XGUI_ActionsMgr.h | 18 +- src/XGUI/XGUI_Workshop.cpp | 68 +----- src/XGUI/XGUI_Workshop.h | 4 - 27 files changed, 431 insertions(+), 304 deletions(-) delete mode 100644 src/PartSet/PartSet_OperationSketch.cpp delete mode 100644 src/PartSet/PartSet_OperationSketch.h diff --git a/src/Model/Model_Session.cpp b/src/Model/Model_Session.cpp index 9e87c0560..94f6cf2a8 100644 --- a/src/Model/Model_Session.cpp +++ b/src/Model/Model_Session.cpp @@ -291,6 +291,14 @@ void Model_Session::registerPlugin(ModelAPI_Plugin* thePlugin) static Events_ID EVENT_LOAD = Events_Loop::loop()->eventByName(EVENT_PLUGIN_LOADED); ModelAPI_EventCreator::get()->sendUpdated(ObjectPtr(), EVENT_LOAD); Events_Loop::loop()->flush(EVENT_LOAD); + // If the plugin has an ability to process GUI events, register it + Events_Listener* aListener = dynamic_cast(thePlugin); + if (aListener) { + Events_Loop* aLoop = Events_Loop::loop(); + static Events_ID aStateRequestEventId = + Events_Loop::loop()->eventByName(EVENT_FEATURE_STATE_REQUEST); + aLoop->registerListener(aListener, aStateRequestEventId); + } } ModelAPI_ValidatorsFactory* Model_Session::validators() diff --git a/src/Model/Model_Validator.cpp b/src/Model/Model_Validator.cpp index dee9841c3..c2c994da9 100644 --- a/src/Model/Model_Validator.cpp +++ b/src/Model/Model_Validator.cpp @@ -90,7 +90,7 @@ void Model_ValidatorsFactory::validators(const std::string& theFeatureID, } } } - addDefaultValidators(theResult); + addDefaultValidators(theResult, theArguments); } void Model_ValidatorsFactory::validators(const std::string& theFeatureID, @@ -134,13 +134,15 @@ const ModelAPI_Validator* Model_ValidatorsFactory::validator(const std::string& return NULL; } -void Model_ValidatorsFactory::addDefaultValidators(std::list& theValidators) const +void Model_ValidatorsFactory::addDefaultValidators(std::list& theValidators, + std::list >& theArguments) const { const static std::string kDefaultId = "Model_FeatureValidator"; std::map::const_iterator it = myIDs.find(kDefaultId); if(it == myIDs.end()) return; theValidators.push_back(it->second); + theArguments.push_back(std::list()); } bool Model_ValidatorsFactory::validate(const std::shared_ptr& theFeature) const diff --git a/src/Model/Model_Validator.h b/src/Model/Model_Validator.h index 35e2d18c0..e2f67b617 100644 --- a/src/Model/Model_Validator.h +++ b/src/Model/Model_Validator.h @@ -89,7 +89,8 @@ class Model_ValidatorsFactory : public ModelAPI_ValidatorsFactory virtual bool isConcealed(std::string theFeature, std::string theAttribute); protected: - void addDefaultValidators(std::list& theValidators) const; + void addDefaultValidators(std::list& theValidators, + std::list >& theArguments) const; /// Get instance from Session Model_ValidatorsFactory(); diff --git a/src/ModelAPI/ModelAPI_Events.cpp b/src/ModelAPI/ModelAPI_Events.cpp index b219a9adf..447019a2a 100644 --- a/src/ModelAPI/ModelAPI_Events.cpp +++ b/src/ModelAPI/ModelAPI_Events.cpp @@ -34,3 +34,53 @@ ModelAPI_ObjectDeletedMessage::~ModelAPI_ObjectDeletedMessage() } +ModelAPI_FeatureStateMessage::ModelAPI_FeatureStateMessage(const Events_ID theID, + const void* theSender) + : Events_Message(theID, theSender) +{ + myCurrentFeature = std::shared_ptr(); +} + +ModelAPI_FeatureStateMessage::~ModelAPI_FeatureStateMessage() +{ + +} + +std::shared_ptr ModelAPI_FeatureStateMessage::feature() const +{ + return myCurrentFeature; +} + +void ModelAPI_FeatureStateMessage::setFeature(std::shared_ptr& theFeature) +{ + myCurrentFeature = theFeature; +} + +bool ModelAPI_FeatureStateMessage::hasState(const std::string& theKey) const +{ + return myFeatureState.find(theKey) != myFeatureState.end(); +} + +bool ModelAPI_FeatureStateMessage::state(const std::string& theFeatureId, bool theDefault) const +{ + if(hasState(theFeatureId)) { + return myFeatureState.at(theFeatureId); + } + return theDefault; +} + +void ModelAPI_FeatureStateMessage::setState(const std::string& theFeatureId, bool theValue) +{ + myFeatureState[theFeatureId] = theValue; +} + +std::list ModelAPI_FeatureStateMessage::features() const +{ + std::list result; + std::map::const_iterator it = myFeatureState.begin(); + for( ; it != myFeatureState.end(); ++it) { + result.push_back(it->first); + } + return result; +} + diff --git a/src/ModelAPI/ModelAPI_Events.h b/src/ModelAPI/ModelAPI_Events.h index 5e6816271..26441f253 100644 --- a/src/ModelAPI/ModelAPI_Events.h +++ b/src/ModelAPI/ModelAPI_Events.h @@ -9,11 +9,13 @@ #include #include +#include #include #include #include #include +#include class ModelAPI_Document; @@ -37,6 +39,9 @@ static const char * EVENT_OBJECT_TOSHOW = "ObjectShow"; /// Event ID that data of feature has to be shown (comes with ModelAPI_ObjectUpdatedMessage) static const char * EVENT_OBJECT_TOHIDE = "ObjectHide"; +static const char * EVENT_FEATURE_STATE_REQUEST = "FeatureStateRequest"; +static const char * EVENT_FEATURE_STATE_RESPONSE = "FeatureStateResponse"; + /// Message that feature was changed (used for Object Browser update): moved, updated and deleted class MODELAPI_EXPORT ModelAPI_ObjectUpdatedMessage : public Events_MessageGroup { @@ -94,4 +99,27 @@ class MODELAPI_EXPORT ModelAPI_EventCreator static void set(const ModelAPI_EventCreator* theCreator); }; +// TODO(sbh): Move this message into a separate package, like "GuiAPI" +class ModelAPI_FeatureStateMessage : public Events_Message +{ + public: + MODELAPI_EXPORT ModelAPI_FeatureStateMessage(const Events_ID theID, const void* theSender = 0); + MODELAPI_EXPORT virtual ~ModelAPI_FeatureStateMessage(); + + // For request + MODELAPI_EXPORT std::shared_ptr feature() const; + MODELAPI_EXPORT void setFeature(std::shared_ptr& theFeature); + // For response + MODELAPI_EXPORT bool hasState(const std::string& theFeatureId) const; + MODELAPI_EXPORT bool state(const std::string& theFeatureId, bool theDefault = false) const; + MODELAPI_EXPORT void setState(const std::string& theFeatureId, bool theValue); + MODELAPI_EXPORT std::list features() const; + + private: + // For Request + std::shared_ptr myCurrentFeature; + // For response + std::map myFeatureState; +}; + #endif diff --git a/src/ModelAPI/ModelAPI_Plugin.h b/src/ModelAPI/ModelAPI_Plugin.h index 829cb750f..c3fc113f7 100644 --- a/src/ModelAPI/ModelAPI_Plugin.h +++ b/src/ModelAPI/ModelAPI_Plugin.h @@ -34,7 +34,6 @@ class MODELAPI_EXPORT ModelAPI_Plugin ModelAPI_Plugin() { } - ; }; #endif diff --git a/src/ModuleBase/ModuleBase_Operation.cpp b/src/ModuleBase/ModuleBase_Operation.cpp index 301fbcca5..00e90732e 100644 --- a/src/ModuleBase/ModuleBase_Operation.cpp +++ b/src/ModuleBase/ModuleBase_Operation.cpp @@ -72,11 +72,6 @@ bool ModuleBase_Operation::isValid() const return aFactory->validate(myFeature); } -bool ModuleBase_Operation::isNestedOperationsEnabled() const -{ - return true; -} - //void ModuleBase_Operation::storeCustomValue() //{ // if (!myFeature) { @@ -364,4 +359,4 @@ void ModuleBase_Operation::setPropertyPanel(ModuleBase_IPropertyPanel* theProp) bool ModuleBase_Operation::isGranted(QString theId) const { return myNestedFeatures.contains(theId); -} \ No newline at end of file +} diff --git a/src/ModuleBase/ModuleBase_Operation.h b/src/ModuleBase/ModuleBase_Operation.h index 4e76077f2..a9333a7e8 100644 --- a/src/ModuleBase/ModuleBase_Operation.h +++ b/src/ModuleBase/ModuleBase_Operation.h @@ -100,11 +100,6 @@ Q_OBJECT */ virtual bool isValid() const; - /// Returns whether the nested operations are enabled. - /// The state can depend on the operation current state. - /// \return enabled state - virtual bool isNestedOperationsEnabled() const; - /// Sets the operation feature void setFeature(FeaturePtr theFeature); diff --git a/src/ModuleBase/ModuleBase_SelectionValidator.h b/src/ModuleBase/ModuleBase_SelectionValidator.h index 78a29cdfa..180d59936 100644 --- a/src/ModuleBase/ModuleBase_SelectionValidator.h +++ b/src/ModuleBase/ModuleBase_SelectionValidator.h @@ -12,10 +12,18 @@ #include +#include +#include + class ModuleBase_SelectionValidator : public ModelAPI_Validator { public: virtual bool isValid(const ModuleBase_ISelection* theSelection) const = 0; + virtual bool isValid(const ModuleBase_ISelection* theSelection, + const std::list& theArguments) const + { + return isValid(theSelection); + } }; #endif diff --git a/src/PartSet/CMakeLists.txt b/src/PartSet/CMakeLists.txt index a3aba0ede..fc2f4b0b8 100644 --- a/src/PartSet/CMakeLists.txt +++ b/src/PartSet/CMakeLists.txt @@ -15,7 +15,6 @@ SET(PROJECT_HEADERS PartSet_WidgetPoint2d.h PartSet_WidgetPoint2dDistance.h PartSet_WidgetShapeSelector.h - PartSet_OperationSketch.h PartSet_Filters.h ) @@ -28,7 +27,6 @@ SET(PROJECT_SOURCES PartSet_WidgetPoint2d.cpp PartSet_WidgetPoint2dDistance.cpp PartSet_WidgetShapeSelector.cpp - PartSet_OperationSketch.cpp PartSet_Filters.cpp ) diff --git a/src/PartSet/PartSet_Module.cpp b/src/PartSet/PartSet_Module.cpp index b13d3542e..c154d43d4 100644 --- a/src/PartSet/PartSet_Module.cpp +++ b/src/PartSet/PartSet_Module.cpp @@ -1,7 +1,6 @@ // Copyright (C) 2014-20xx CEA/DEN, EDF R&D #include "PartSet_Module.h" -#include #include #include #include @@ -139,6 +138,7 @@ void PartSet_Module::registerValidators() aFactory->registerValidator("PartSet_PerpendicularValidator", new PartSet_PerpendicularValidator); aFactory->registerValidator("PartSet_ParallelValidator", new PartSet_ParallelValidator); aFactory->registerValidator("PartSet_RadiusValidator", new PartSet_RadiusValidator); + aFactory->registerValidator("PartSet_RigidValidator", new PartSet_RigidValidator); aFactory->registerValidator("PartSet_DifferentObjects", new PartSet_DifferentObjectsValidator); } @@ -464,16 +464,6 @@ void PartSet_Module::launchEditing() } } -/// Returns new instance of operation object (used in createOperation for customization) -ModuleBase_Operation* PartSet_Module::getNewOperation(const std::string& theFeatureId) -{ - if (theFeatureId == PartSet_OperationSketch::Type()) { - return new PartSet_OperationSketch(theFeatureId.c_str(), this); - } - return ModuleBase_IModule::getNewOperation(theFeatureId); -} - - void PartSet_Module::onMouseReleased(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent) { myWorkshop->viewer()->enableSelection(true); diff --git a/src/PartSet/PartSet_Module.h b/src/PartSet/PartSet_Module.h index 70e4141ca..e04148a1d 100644 --- a/src/PartSet/PartSet_Module.h +++ b/src/PartSet/PartSet_Module.h @@ -117,9 +117,6 @@ protected slots: void launchEditing(); protected: - /// Returns new instance of operation object (used in createOperation for customization) - virtual ModuleBase_Operation* getNewOperation(const std::string& theFeatureId); - /// Register validators for this module virtual void registerValidators(); diff --git a/src/PartSet/PartSet_OperationSketch.cpp b/src/PartSet/PartSet_OperationSketch.cpp deleted file mode 100644 index b2677b547..000000000 --- a/src/PartSet/PartSet_OperationSketch.cpp +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (C) 2014-20xx CEA/DEN, EDF R&D - -// File: PartSet_OperationSketch.h -// Created: 20 Apr 2014 -// Author: Natalia ERMOLAEVA - -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include - -#ifdef _DEBUG -#include -#endif - -#include - -using namespace std; - -PartSet_OperationSketch::PartSet_OperationSketch(const QString& theId, QObject* theParent) - : ModuleBase_Operation(theId, theParent) -{ -} - -PartSet_OperationSketch::~PartSet_OperationSketch() -{ -} - -bool PartSet_OperationSketch::isNestedOperationsEnabled() const -{ - bool aHasSketchPlane = false; - if (feature()) { - std::shared_ptr aData = feature()->data(); - AttributeDoublePtr anAttr; - std::shared_ptr aNormal = std::dynamic_pointer_cast( - aData->attribute(SketchPlugin_Sketch::NORM_ID())); - aHasSketchPlane = aNormal && !(aNormal->x() == 0 && aNormal->y() == 0 && aNormal->z() == 0); - } - return aHasSketchPlane; -} diff --git a/src/PartSet/PartSet_OperationSketch.h b/src/PartSet/PartSet_OperationSketch.h deleted file mode 100644 index d7120dcf4..000000000 --- a/src/PartSet/PartSet_OperationSketch.h +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (C) 2014-20xx CEA/DEN, EDF R&D - -// File: PartSet_OperationSketch.h -// Created: 20 Apr 2014 -// Author: Natalia ERMOLAEVA - -#ifndef PartSet_OperationSketch_H -#define PartSet_OperationSketch_H - -#include "PartSet.h" - -#include -#include - -/*! - \class PartSet_OperationSketch - * \brief The operation for the sketch feature creation - */ -class PARTSET_EXPORT PartSet_OperationSketch : public ModuleBase_Operation -{ -Q_OBJECT - - public: - /// Returns the operation type key - static std::string Type() - { - return SketchPlugin_Sketch::ID(); - } - - /// Constructor - /// \param theId the feature identifier - /// \param theParent the operation parent - PartSet_OperationSketch(const QString& theId, QObject* theParent); - /// Destructor - virtual ~PartSet_OperationSketch(); - - /// Returns whether the nested operations are enabled. - /// The state can depend on the operation current state. - /// It returns true after the sketch plane is choosen. - /// \return enabled state - virtual bool isNestedOperationsEnabled() const; - -}; - -#endif diff --git a/src/PartSet/PartSet_Validators.cpp b/src/PartSet/PartSet_Validators.cpp index 8f026d712..fa7ac518f 100644 --- a/src/PartSet/PartSet_Validators.cpp +++ b/src/PartSet/PartSet_Validators.cpp @@ -18,6 +18,9 @@ #include #include +#ifdef _DEBUG +#include +#endif int shapesNbPoints(const ModuleBase_ISelection* theSelection) { @@ -55,7 +58,7 @@ int shapesNbLines(const ModuleBase_ISelection* theSelection) bool PartSet_DistanceValidator::isValid(const ModuleBase_ISelection* theSelection) const { - int aCount = shapesNbPoints(theSelection); + int aCount = shapesNbPoints(theSelection) + shapesNbLines(theSelection); return (aCount > 0) && (aCount < 3); } @@ -98,7 +101,11 @@ bool PartSet_RadiusValidator::isValid(const ModuleBase_ISelection* theSelection) return (aCount > 0) && (aCount < 2); } - +bool PartSet_RigidValidator::isValid(const ModuleBase_ISelection* theSelection) const +{ + int aCount = shapesNbLines(theSelection); + return (aCount > 0) && (aCount < 2); +} bool PartSet_DifferentObjectsValidator::isValid(const FeaturePtr& theFeature, const std::list& theArguments, @@ -163,4 +170,4 @@ bool PartSet_DifferentObjectsValidator::isValid(const AttributePtr& theAttribute { // not implemented return true; -} \ No newline at end of file +} diff --git a/src/PartSet/PartSet_Validators.h b/src/PartSet/PartSet_Validators.h index 373cd8e13..d0829b586 100644 --- a/src/PartSet/PartSet_Validators.h +++ b/src/PartSet/PartSet_Validators.h @@ -52,6 +52,13 @@ class PartSet_RadiusValidator : public ModuleBase_SelectionValidator PARTSET_EXPORT virtual bool isValid(const ModuleBase_ISelection* theSelection) const; }; +//! A class to validate a selection for Perpendicular constraint operation +class PartSet_RigidValidator : public ModuleBase_SelectionValidator +{ + public: + PARTSET_EXPORT virtual bool isValid(const ModuleBase_ISelection* theSelection) const; +}; + class PartSet_DifferentObjectsValidator : public ModelAPI_RefAttrValidator { public: diff --git a/src/PartSetPlugin/CMakeLists.txt b/src/PartSetPlugin/CMakeLists.txt index 1b10b60c7..cd3dcad94 100644 --- a/src/PartSetPlugin/CMakeLists.txt +++ b/src/PartSetPlugin/CMakeLists.txt @@ -26,6 +26,7 @@ ADD_LIBRARY(PartSetPlugin MODULE ${PROJECT_SOURCES} ${PROJECT_HEADERS} ${XML_RES TARGET_LINK_LIBRARIES(PartSetPlugin ${PROJECT_LIBRARIES} ModelAPI) INCLUDE_DIRECTORIES( + ../Events ../ModelAPI ../GeomAPI ) diff --git a/src/PartSetPlugin/PartSetPlugin_Plugin.cpp b/src/PartSetPlugin/PartSetPlugin_Plugin.cpp index 2869895bf..c4d504346 100644 --- a/src/PartSetPlugin/PartSetPlugin_Plugin.cpp +++ b/src/PartSetPlugin/PartSetPlugin_Plugin.cpp @@ -4,9 +4,16 @@ #include "PartSetPlugin_Part.h" #include "PartSetPlugin_Duplicate.h" #include "PartSetPlugin_Remove.h" + +#include + #include #include +#ifdef _DEBUG +#include +#endif + using namespace std; // the only created instance of this plugin @@ -32,3 +39,31 @@ FeaturePtr PartSetPlugin_Plugin::createFeature(string theFeatureID) // feature of such kind is not found return FeaturePtr(); } + +void PartSetPlugin_Plugin::processEvent(const std::shared_ptr& theMessage) +{ + const Events_ID kRequestEvent = + Events_Loop::loop()->eventByName(EVENT_FEATURE_STATE_REQUEST); + if (theMessage->eventID() == kRequestEvent) { + Events_Loop::loop()->send(getFeaturesState(), false); + } else if (theMessage.get()) { + #ifdef _DEBUG + std::cout << "PartSetPlugin_Plugin::processEvent: unhandled message caught: " << std::endl + << theMessage->eventID().eventText() << std::endl; + #endif + } +} + +std::shared_ptr PartSetPlugin_Plugin::getFeaturesState() +{ + const Events_ID kResponseEvent = + Events_Loop::loop()->eventByName(EVENT_FEATURE_STATE_RESPONSE); + std::shared_ptr aMsg = + std::make_shared(kResponseEvent, this); + std::string aStdDocKind = ModelAPI_Session::get()->activeDocument()->kind(); + bool aDocIsPart = (aStdDocKind == PartSetPlugin_Part::ID()); + aMsg->setState(PartSetPlugin_Part::ID(), true); + aMsg->setState(PartSetPlugin_Duplicate::ID(), aDocIsPart); + aMsg->setState(PartSetPlugin_Remove::ID(), aDocIsPart); + return aMsg; +} diff --git a/src/PartSetPlugin/PartSetPlugin_Plugin.h b/src/PartSetPlugin/PartSetPlugin_Plugin.h index 9969cb403..364ebb48d 100644 --- a/src/PartSetPlugin/PartSetPlugin_Plugin.h +++ b/src/PartSetPlugin/PartSetPlugin_Plugin.h @@ -7,19 +7,28 @@ #ifndef PartSetPlugin_Plugin_H_ #define PartSetPlugin_Plugin_H_ -#include "PartSetPlugin.h" -#include "ModelAPI_Plugin.h" -#include "ModelAPI_Feature.h" +#include +#include +#include +#include -class PARTSETPLUGIN_EXPORT PartSetPlugin_Plugin : public ModelAPI_Plugin +#include + +#include + +class PARTSETPLUGIN_EXPORT PartSetPlugin_Plugin : public ModelAPI_Plugin, + public Events_Listener { public: /// Creates the feature object of this plugin by the feature string ID virtual FeaturePtr createFeature(std::string theFeatureID); - public: /// Is needed for python wrapping by swig PartSetPlugin_Plugin(); + + //! Redefinition of Events_Listener method + virtual void processEvent(const std::shared_ptr& theMessage); + std::shared_ptr getFeaturesState(); }; #endif diff --git a/src/SketchPlugin/CMakeLists.txt b/src/SketchPlugin/CMakeLists.txt index 16cbcccde..d801aabac 100644 --- a/src/SketchPlugin/CMakeLists.txt +++ b/src/SketchPlugin/CMakeLists.txt @@ -64,6 +64,7 @@ TARGET_LINK_LIBRARIES(SketchPlugin ${PROJECT_LIBRARIES}) INCLUDE_DIRECTORIES( ../Config + ../Events ../ModelAPI ../GeomAPI ../GeomAlgoAPI diff --git a/src/SketchPlugin/SketchPlugin_Plugin.cpp b/src/SketchPlugin/SketchPlugin_Plugin.cpp index 7035cff11..6680aef33 100644 --- a/src/SketchPlugin/SketchPlugin_Plugin.cpp +++ b/src/SketchPlugin/SketchPlugin_Plugin.cpp @@ -1,26 +1,37 @@ // Copyright (C) 2014-20xx CEA/DEN, EDF R&D --> -#include "SketchPlugin_Plugin.h" -#include "SketchPlugin_Sketch.h" -#include "SketchPlugin_Line.h" -#include "SketchPlugin_Point.h" -#include "SketchPlugin_Circle.h" -#include "SketchPlugin_Arc.h" -#include "SketchPlugin_ConstraintCoincidence.h" -#include "SketchPlugin_ConstraintDistance.h" -#include "SketchPlugin_ConstraintLength.h" -#include "SketchPlugin_ConstraintParallel.h" -#include "SketchPlugin_ConstraintPerpendicular.h" -#include "SketchPlugin_ConstraintRadius.h" -#include "SketchPlugin_ConstraintRigid.h" -#include "SketchPlugin_Validators.h" -#include "SketchPlugin_ResultValidators.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + #include #include #include +#include #include +#include + +#ifdef _DEBUG +#include +#endif + using namespace std; // the only created instance of this plugin @@ -94,3 +105,45 @@ FeaturePtr SketchPlugin_Plugin::createFeature(string theFeatureID) // feature of such kind is not found return FeaturePtr(); } + +void SketchPlugin_Plugin::processEvent(const std::shared_ptr& theMessage) +{ + const Events_ID kRequestEvent = + Events_Loop::loop()->eventByName(EVENT_FEATURE_STATE_REQUEST); + if (theMessage->eventID() == kRequestEvent) { + std::shared_ptr aStateMessage = + std::dynamic_pointer_cast(theMessage); + Events_Loop::loop()->send(getFeaturesState(aStateMessage->feature()), false); + } +} + +std::shared_ptr SketchPlugin_Plugin +::getFeaturesState(const std::shared_ptr& theFeature) const +{ + const Events_ID kResponseEvent = Events_Loop::loop()->eventByName(EVENT_FEATURE_STATE_RESPONSE); + std::shared_ptr aMsg = + std::make_shared(kResponseEvent, this); + + bool aHasSketchPlane = false; + std::shared_ptr aSketchFeature = + std::dynamic_pointer_cast(theFeature); + if (aSketchFeature.get()) { + std::shared_ptr aData = aSketchFeature->data(); + std::shared_ptr aNormal = + std::dynamic_pointer_cast(aData->attribute(SketchPlugin_Sketch::NORM_ID())); + aHasSketchPlane = aNormal && !(aNormal->x() == 0 && aNormal->y() == 0 && aNormal->z() == 0); + + aMsg->setState(SketchPlugin_Point::ID(), aHasSketchPlane); + aMsg->setState(SketchPlugin_Line::ID(), aHasSketchPlane); + aMsg->setState(SketchPlugin_Circle::ID(), aHasSketchPlane); + aMsg->setState(SketchPlugin_Arc::ID(), aHasSketchPlane); + aMsg->setState(SketchPlugin_ConstraintCoincidence::ID(), aHasSketchPlane); + aMsg->setState(SketchPlugin_ConstraintDistance::ID(), aHasSketchPlane); + aMsg->setState(SketchPlugin_ConstraintLength::ID(), aHasSketchPlane); + aMsg->setState(SketchPlugin_ConstraintParallel::ID(), aHasSketchPlane); + aMsg->setState(SketchPlugin_ConstraintPerpendicular::ID(), aHasSketchPlane); + aMsg->setState(SketchPlugin_ConstraintRadius::ID(), aHasSketchPlane); + aMsg->setState(SketchPlugin_ConstraintRigid::ID(), aHasSketchPlane); + } + return aMsg; +} diff --git a/src/SketchPlugin/SketchPlugin_Plugin.h b/src/SketchPlugin/SketchPlugin_Plugin.h index dab7e9b1c..fad6fa739 100644 --- a/src/SketchPlugin/SketchPlugin_Plugin.h +++ b/src/SketchPlugin/SketchPlugin_Plugin.h @@ -4,14 +4,16 @@ // Created: 31 Mar 2014 // Author: Mikhail PONIKAROV -#ifndef SketchPlugin_Plugin_H_ -#define SketchPlugin_Plugin_H_ +#ifndef SKETCHPLUGIN_PLUGIN_H_ +#define SKETCHPLUGIN_PLUGIN_H_ -#include "SketchPlugin.h" -#include "ModelAPI_Plugin.h" -#include "ModelAPI_Feature.h" +#include +#include +#include +#include +#include -class SKETCHPLUGIN_EXPORT SketchPlugin_Plugin : public ModelAPI_Plugin +class SKETCHPLUGIN_EXPORT SketchPlugin_Plugin : public ModelAPI_Plugin, public Events_Listener { public: /// Creates the feature object of this plugin by the feature string ID @@ -20,6 +22,11 @@ class SKETCHPLUGIN_EXPORT SketchPlugin_Plugin : public ModelAPI_Plugin public: /// Is needed for python wrapping by swig SketchPlugin_Plugin(); + //! Redefinition of Events_Listener method + virtual void processEvent(const std::shared_ptr& theMessage); + protected: + std::shared_ptr getFeaturesState( + const std::shared_ptr& theFeature) const; }; #endif diff --git a/src/SketchPlugin/plugin-Sketch.xml b/src/SketchPlugin/plugin-Sketch.xml index 14b18da74..571c97d77 100644 --- a/src/SketchPlugin/plugin-Sketch.xml +++ b/src/SketchPlugin/plugin-Sketch.xml @@ -105,12 +105,13 @@ - + diff --git a/src/XGUI/XGUI_ActionsMgr.cpp b/src/XGUI/XGUI_ActionsMgr.cpp index 36179f2a4..851e3fef0 100644 --- a/src/XGUI/XGUI_ActionsMgr.cpp +++ b/src/XGUI/XGUI_ActionsMgr.cpp @@ -4,18 +4,25 @@ * XGUI_ActionsMgr.cpp */ -#include "XGUI_ActionsMgr.h" -#include "XGUI_Workshop.h" -#include "XGUI_OperationMgr.h" -#include "XGUI_SalomeConnector.h" - #include -#include +#include +#include +#include +#include +#include +#include -#include +#include #include +#include +#include +#include +#include +#include + + #include #ifdef _DEBUG @@ -34,6 +41,12 @@ XGUI_ActionsMgr::XGUI_ActionsMgr(XGUI_Workshop* theParent) myShortcuts << QKeySequence::Redo; myShortcuts << QKeySequence::Open; myShortcuts << QKeySequence::Close; + + //Initialize event listening + Events_Loop* aLoop = Events_Loop::loop(); + static Events_ID aStateResponseEventId = + Events_Loop::loop()->eventByName(EVENT_FEATURE_STATE_RESPONSE); + aLoop->registerListener(this, aStateResponseEventId, NULL, true); } XGUI_ActionsMgr::~XGUI_ActionsMgr() @@ -61,45 +74,144 @@ void XGUI_ActionsMgr::addNestedCommands(const QString& theId, const QStringList& myNestedActions[theId] = theCommands; } +QStringList XGUI_ActionsMgr::nestedCommands(const QString& theId) const +{ + if (myNestedActions.contains(theId)) + return myNestedActions[theId]; + return QStringList(); +} + +bool XGUI_ActionsMgr::isNested(const QString& theId) const +{ + foreach(QString aId, myNestedActions.keys()) + { + QStringList aList = myNestedActions[aId]; + if (aList.contains(theId)) + return true; + } + return false; +} + void XGUI_ActionsMgr::update() { + FeaturePtr anActiveFeature = FeaturePtr(); if (myOperationMgr->hasOperation()) { ModuleBase_Operation* anOperation = myOperationMgr->currentOperation(); - FeaturePtr aFeature = anOperation->feature(); - if(aFeature) { + anActiveFeature = anOperation->feature(); + if(anActiveFeature.get()) { setAllEnabled(false); - QString aFeatureId = QString::fromStdString(aFeature->getKind()); + QString aFeatureId = QString::fromStdString(anActiveFeature->getKind()); setActionEnabled(aFeatureId, true); - setNestedStackEnabled(anOperation); } + setNestedStackEnabled(anOperation); } else { setAllEnabled(true); setNestedCommandsEnabled(false); } + // TODO(SBH): Get defaults state of actions from XML and remove the following method updateByDocumentKind(); updateCheckState(); + updateByPlugins(anActiveFeature); } -void XGUI_ActionsMgr::setAllEnabled(bool isEnabled) +void XGUI_ActionsMgr::updateCheckState() { - foreach(QString eachAction, myActions.keys()) - { - setActionEnabled(eachAction, isEnabled); + QString eachCommand = QString(); + foreach(eachCommand, myActions.keys()) { + setActionChecked(eachCommand, false); + } + QStringList ltActiveCommands = myOperationMgr->operationList(); + foreach(eachCommand, ltActiveCommands) { + setActionChecked(eachCommand, true); } } -void XGUI_ActionsMgr::setNestedStackEnabled(ModuleBase_Operation* theOperation) +void XGUI_ActionsMgr::updateOnViewSelection() { - if(!theOperation || !theOperation->feature()) + XGUI_Selection* aSelection = myWorkshop->selector()->selection(); + if (aSelection->getSelected().size() == 0 || !myOperationMgr->hasOperation()) return; - FeaturePtr aFeature = theOperation->feature(); - QString aFeatureId = QString::fromStdString(aFeature->getKind()); - bool isNestedEnabled = theOperation->isNestedOperationsEnabled(); - setNestedCommandsEnabled(isNestedEnabled, aFeatureId); + ModuleBase_Operation* anOperation = myOperationMgr->currentOperation(); + FeaturePtr anActiveFeature = anOperation->feature(); + if(!anActiveFeature.get()) + return; + QString aFeatureId = QString::fromStdString(anActiveFeature->getKind()); - setNestedStackEnabled(myOperationMgr->previousOperation(theOperation)); + SessionPtr aMgr = ModelAPI_Session::get(); + ModelAPI_ValidatorsFactory* aFactory = aMgr->validators(); + foreach(QString aId, nestedCommands(aFeatureId)) { + std::list aValidators; + std::list > anArguments; + if (!anArguments.empty()) { + std::list firstArg = anArguments.front(); + } + aFactory->validators(aId.toStdString(), aValidators, anArguments); + std::list::iterator aValidator = aValidators.begin(); + std::list >::iterator aValidatorArgs = anArguments.begin(); + for (; aValidator != aValidators.end(); aValidator++, aValidatorArgs++) { + if (!(*aValidator)) + continue; + const ModuleBase_SelectionValidator* aSelValidator = + dynamic_cast(*aValidator); + if (!aSelValidator) + continue; + setActionEnabled(aId, aSelValidator->isValid(aSelection, *aValidatorArgs)); + + } + } +} + +QKeySequence XGUI_ActionsMgr::registerShortcut(const QString& theKeySequence) +{ + if (theKeySequence.isEmpty()) { + return QKeySequence(); + } + QKeySequence aResult(theKeySequence); + if (myShortcuts.contains(aResult)) { + QString aMessage = tr("Shortcut %1 is already defined. Ignore.").arg(theKeySequence); + Events_Error::send(aMessage.toStdString()); + return QKeySequence(); + } + myShortcuts.append(aResult); + return aResult; +} + +void XGUI_ActionsMgr::processEvent(const std::shared_ptr& theMessage) +{ + const Events_ID kResponseEvent = + Events_Loop::loop()->eventByName(EVENT_FEATURE_STATE_RESPONSE); + if (theMessage->eventID() == kResponseEvent) { + std::shared_ptr aStateMessage = + std::dynamic_pointer_cast(theMessage); + if (!aStateMessage.get()) + return; + std::list aFeaturesList = aStateMessage->features(); + std::list::iterator it = aFeaturesList.begin(); + for( ; it != aFeaturesList.end(); ++it) { + QString anActionId = QString::fromStdString(*it); + bool theDefaultState = false; + if (myActions.contains(anActionId)) { + theDefaultState = myActions[anActionId]->isEnabled(); + } + setActionEnabled(anActionId, aStateMessage->state(*it, theDefaultState)); + } + } else if (theMessage.get()) { + #ifdef _DEBUG + std::cout << "XGUI_ActionsMgr::processEvent: unhandled message caught: " << std::endl + << theMessage->eventID().eventText() << std::endl; + #endif + } +} + +void XGUI_ActionsMgr::setAllEnabled(bool isEnabled) +{ + foreach(QString eachAction, myActions.keys()) + { + setActionEnabled(eachAction, isEnabled); + } } + //! void XGUI_ActionsMgr::setNestedCommandsEnabled(bool theEnabled, const QString& theParent) { @@ -116,6 +228,17 @@ void XGUI_ActionsMgr::setNestedCommandsEnabled(bool theEnabled, const QString& t } } +void XGUI_ActionsMgr::setNestedStackEnabled(ModuleBase_Operation* theOperation) +{ + if(!theOperation || !theOperation->feature()) + return; + FeaturePtr aFeature = theOperation->feature(); + QString aFeatureId = QString::fromStdString(aFeature->getKind()); + setNestedCommandsEnabled(true, aFeatureId); + + setNestedStackEnabled(myOperationMgr->previousOperation(theOperation)); +} + void XGUI_ActionsMgr::setActionChecked(const QString& theId, const bool theChecked) { if (myActions.contains(theId)) { @@ -126,6 +249,13 @@ void XGUI_ActionsMgr::setActionChecked(const QString& theId, const bool theCheck } } +void XGUI_ActionsMgr::setActionEnabled(const QString& theId, const bool theEnabled) +{ + if (myActions.contains(theId)) { + myActions[theId]->setEnabled(theEnabled); + } +} + /* * Disables all actions which have the Document Kind different to * the current document's kind @@ -152,54 +282,12 @@ void XGUI_ActionsMgr::updateByDocumentKind() } } -void XGUI_ActionsMgr::setActionEnabled(const QString& theId, const bool theEnabled) -{ - if (myActions.contains(theId)) { - myActions[theId]->setEnabled(theEnabled); - } -} - -void XGUI_ActionsMgr::updateCheckState() -{ - QString eachCommand = QString(); - foreach(eachCommand, myActions.keys()) { - setActionChecked(eachCommand, false); - } - QStringList ltActiveCommands = myOperationMgr->operationList(); - foreach(eachCommand, ltActiveCommands) { - setActionChecked(eachCommand, true); - } -} - -QStringList XGUI_ActionsMgr::nestedCommands(const QString& theId) const -{ - if (myNestedActions.contains(theId)) - return myNestedActions[theId]; - return QStringList(); -} - -bool XGUI_ActionsMgr::isNested(const QString& theId) const -{ - foreach(QString aId, myNestedActions.keys()) - { - QStringList aList = myNestedActions[aId]; - if (aList.contains(theId)) - return true; - } - return false; -} - -QKeySequence XGUI_ActionsMgr::registerShortcut(const QString& theKeySequence) +void XGUI_ActionsMgr::updateByPlugins(FeaturePtr anActiveFeature) { - if (theKeySequence.isEmpty()) { - return QKeySequence(); - } - QKeySequence aResult(theKeySequence); - if (myShortcuts.contains(aResult)) { - QString aMessage = tr("Shortcut %1 is already defined. Ignore.").arg(theKeySequence); - Events_Error::send(aMessage.toStdString()); - return QKeySequence(); - } - myShortcuts.append(aResult); - return aResult; + static Events_ID aStateRequestEventId = Events_Loop::loop()->eventByName( + EVENT_FEATURE_STATE_REQUEST); + std::shared_ptr aMsg = + std::make_shared(aStateRequestEventId, this); + aMsg->setFeature(anActiveFeature); + Events_Loop::loop()->send(aMsg, false); } diff --git a/src/XGUI/XGUI_ActionsMgr.h b/src/XGUI/XGUI_ActionsMgr.h index 289b85510..3101cb0bd 100644 --- a/src/XGUI/XGUI_ActionsMgr.h +++ b/src/XGUI/XGUI_ActionsMgr.h @@ -9,6 +9,9 @@ #include "XGUI.h" +#include +#include + #include #include #include @@ -20,7 +23,7 @@ class XGUI_OperationMgr; class ModuleBase_Operation; class QAction; -class XGUI_EXPORT XGUI_ActionsMgr : public QObject +class XGUI_EXPORT XGUI_ActionsMgr : public QObject, public Events_Listener { Q_OBJECT @@ -41,7 +44,8 @@ Q_OBJECT QKeySequence registerShortcut(const QString& theKeySequence); - void updateByDocumentKind(); + //! Redefinition of Events_Listener method + virtual void processEvent(const std::shared_ptr& theMessage); public slots: //! Update workbench actions according to OperationMgr state: @@ -51,19 +55,25 @@ Q_OBJECT void update(); //! Sets all commands checked if it's operation is active. void updateCheckState(); + //! Updates actions according to current selection in the viewer + void updateOnViewSelection(); protected: //! Sets all actions to isEnabled state. void setAllEnabled(bool isEnabled); - //! Sets to isEnabled state all siblings of the given operation and it's parents recursively - void setNestedStackEnabled(ModuleBase_Operation* theOperation); //! Sets all nested actions to isEnabled state for the command with given ID. //! If ID is empty - all nested actions will be affected. void setNestedCommandsEnabled(bool isEnabled, const QString& theParent = QString()); + //! Sets to enabled state all siblings of the given operation and it's parents recursively + void setNestedStackEnabled(ModuleBase_Operation* theOperation); //! Sets the action with theId to theChecked state. void setActionChecked(const QString& theId, const bool theChecked); //! Sets the action with theId to theEnabled state. void setActionEnabled(const QString& theId, const bool theEnabled); + //! Updates actions according to their "document" tag + void updateByDocumentKind(); + //! Asks plugins about their features state, using the Events system + void updateByPlugins(FeaturePtr theActiveFeature); private: QMap myActions; diff --git a/src/XGUI/XGUI_Workshop.cpp b/src/XGUI/XGUI_Workshop.cpp index d28799f32..39d1254f3 100644 --- a/src/XGUI/XGUI_Workshop.cpp +++ b/src/XGUI/XGUI_Workshop.cpp @@ -97,8 +97,10 @@ QIcon XGUI_Workshop::featureIcon(const FeaturePtr& theFeature) ModelAPI_ExecState aState = theFeature->data()->execState(); switch(aState) { case ModelAPI_StateDone: - case ModelAPI_StateNothing: + case ModelAPI_StateNothing: { anIcon = QIcon(anIconString); + } + break; case ModelAPI_StateMustBeUpdated: { anIcon = ModuleBase_Tools::lighter(anIconString); } @@ -143,7 +145,8 @@ XGUI_Workshop::XGUI_Workshop(XGUI_SalomeConnector* theConnector) SLOT(onContextMenuCommand(const QString&, bool))); myViewerProxy = new XGUI_ViewerProxy(this); - connect(myViewerProxy, SIGNAL(selectionChanged()), this, SLOT(updateCommandsOnViewSelection())); + connect(myViewerProxy, SIGNAL(selectionChanged()), + myActionsMgr, SLOT(updateOnViewSelection())); myModuleConnector = new XGUI_ModuleConnector(this); @@ -158,11 +161,6 @@ XGUI_Workshop::XGUI_Workshop(XGUI_SalomeConnector* theConnector) connect(myOperationMgr, SIGNAL(operationAborted(ModuleBase_Operation*)), SLOT(onOperationAborted(ModuleBase_Operation*))); connect(myMainWindow, SIGNAL(exitKeySequence()), SLOT(onExit())); - // TODO(sbh): It seems that application works properly without update on operationStarted - connect(myOperationMgr, SIGNAL(operationStarted(ModuleBase_Operation*)), - myActionsMgr, SLOT(update())); - connect(myOperationMgr, SIGNAL(operationStopped(ModuleBase_Operation*)), - myActionsMgr, SLOT(update())); connect(this, SIGNAL(errorOccurred(const QString&)), myErrorDlg, SLOT(addError(const QString&))); } @@ -1074,22 +1072,6 @@ void XGUI_Workshop::updateCommandStatus() myActionsMgr->update(); } -//****************************************************** -QList XGUI_Workshop::getModuleCommands() const -{ - QList aCommands; - if (isSalomeMode()) { // update commands in SALOME mode - aCommands = salomeConnector()->commandList(); - } else { - AppElements_MainMenu* aMenuBar = myMainWindow->menuObject(); - foreach(AppElements_Command* aCmd, aMenuBar->features()) - { - aCommands.append(aCmd); - } - } - return aCommands; -} - //****************************************************** QDockWidget* XGUI_Workshop::createObjectBrowser(QWidget* theParent) { @@ -1339,46 +1321,6 @@ void XGUI_Workshop::showOnlyObjects(const QObjectPtrList& theList) } -//************************************************************** -void XGUI_Workshop::updateCommandsOnViewSelection() -{ - XGUI_Selection* aSelection = mySelector->selection(); - if (aSelection->getSelected().size() == 0) - return; - - // Restrict validators to manage only nested (child) features - // of the current feature i.e. if current feature is Sketch - - // Sketch Features & Constraints can be validated. - QStringList aNestedIds; - if(myOperationMgr->hasOperation()) { - FeaturePtr aFeature = myOperationMgr->currentOperation()->feature(); - if(aFeature) { - aNestedIds << myActionsMgr->nestedCommands(QString::fromStdString(aFeature->getKind())); - } - } - SessionPtr aMgr = ModelAPI_Session::get(); - ModelAPI_ValidatorsFactory* aFactory = aMgr->validators(); - QList aActions = getModuleCommands(); - foreach(QAction* aAction, aActions) { - QString aId = aAction->data().toString(); - if(!aNestedIds.contains(aId)) - continue; - std::list aValidators; - std::list > anArguments; - aFactory->validators(aId.toStdString(), aValidators, anArguments); - std::list::iterator aValidator = aValidators.begin(); - for (; aValidator != aValidators.end(); aValidator++) { - if (*aValidator) { - const ModuleBase_SelectionValidator* aSelValidator = - dynamic_cast(*aValidator); - if (aSelValidator) { - aAction->setEnabled(aSelValidator->isValid(aSelection)); - } - } - } - } -} - //************************************************************** void XGUI_Workshop::registerValidators() const { diff --git a/src/XGUI/XGUI_Workshop.h b/src/XGUI/XGUI_Workshop.h index 82fd0ed87..c35db675b 100644 --- a/src/XGUI/XGUI_Workshop.h +++ b/src/XGUI/XGUI_Workshop.h @@ -91,7 +91,6 @@ Q_OBJECT { return myActionsMgr; } - ; //! Returns property panel widget XGUI_PropertyPanel* propertyPanel() const @@ -196,7 +195,6 @@ signals: public slots: void updateCommandStatus(); - void updateCommandsOnViewSelection(); void onNew(); void onOpen(); @@ -241,8 +239,6 @@ signals: void validateOperation(const QString& theOperationId); - QList getModuleCommands() const; - void displayAllResults(); void displayDocumentResults(DocumentPtr theDoc); void displayGroupResults(DocumentPtr theDoc, std::string theGroup); -- 2.39.2