X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FModuleBase%2FModuleBase_IModule.cpp;h=9e7f39de1798c4dcd1ecc9dbaa2428c99c96d403;hb=77ce6d35ac8d2f0fdaecb4f23e0870bf74e36103;hp=c73bf3c1c5081a803b07d15181918d283418eaae;hpb=fb22ba72114328242bb0bd465abbca43321dcfe4;p=modules%2Fshaper.git diff --git a/src/ModuleBase/ModuleBase_IModule.cpp b/src/ModuleBase/ModuleBase_IModule.cpp index c73bf3c1c..9e7f39de1 100644 --- a/src/ModuleBase/ModuleBase_IModule.cpp +++ b/src/ModuleBase/ModuleBase_IModule.cpp @@ -1,30 +1,61 @@ -// Copyright (C) 2014-20xx CEA/DEN, EDF R&D - +// Copyright (C) 2014-2024 CEA, EDF +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "ModelAPI_IReentrant.h" +#include "ModelAPI_EventReentrantMessage.h" #include "ModuleBase_IModule.h" #include "ModuleBase_IViewer.h" #include "ModuleBase_ViewerPrs.h" #include "ModuleBase_Operation.h" +#include "ModuleBase_IPropertyPanel.h" #include "ModuleBase_ISelection.h" #include "ModuleBase_OperationDescription.h" #include "ModuleBase_OperationFeature.h" -#include +#include "ModuleBase_ModelWidget.h" +#include "ModuleBase_WidgetFactory.h" +#include "ModuleBase_PageWidget.h" +#include "ModuleBase_Dialog.h" +#include "ModuleBase_IErrorMgr.h" +#include #include +#include -#include #include #include #include +#include "ModelAPI_Tools.h" #include #include #include #include +#include +#include +#include +#include +#include ModuleBase_IModule::ModuleBase_IModule(ModuleBase_IWorkshop* theParent) - : QObject(theParent), myWorkshop(theParent) + : QObject(theParent), myWorkshop(theParent) { connect(myWorkshop, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged())); @@ -41,95 +72,109 @@ ModuleBase_IModule::ModuleBase_IModule(ModuleBase_IWorkshop* theParent) // SLOT(onMouseDoubleClick(QMouseEvent*))); } -void ModuleBase_IModule::launchOperation(const QString& theCmdId) +ModuleBase_IModule::~ModuleBase_IModule() { - if (!myWorkshop->canStartOperation(theCmdId)) - return; - - ModuleBase_OperationFeature* aFOperation = dynamic_cast - (createOperation(theCmdId.toStdString())); - if (aFOperation) { - ModuleBase_ISelection* aSelection = myWorkshop->selection(); - // Initialise operation with preliminary selection - aFOperation->initSelection(aSelection, myWorkshop->viewer()); - sendOperation(aFOperation); + std::map::const_iterator aFiltersIt = + mySelectionFilters.begin(); + for (; aFiltersIt != mySelectionFilters.end(); aFiltersIt++) { + Handle(SelectMgr_Filter) aFilter = aFiltersIt->second; + if (!aFilter.IsNull()) + aFilter.Nullify(); } } -void ModuleBase_IModule::sendOperation(ModuleBase_Operation* theOperation) +void ModuleBase_IModule::launchModal(const QString& theCmdId) { - static Events_ID aModuleEvent = Events_Loop::eventByName(EVENT_OPERATION_LAUNCHED); - std::shared_ptr aMessage = - std::shared_ptr(new Config_PointerMessage(aModuleEvent, this)); - aMessage->setPointer(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 -} + bool isCommitted; + if (!myWorkshop->canStartOperation(theCmdId, isCommitted)) + return; -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()); - } + std::string aXmlCfg, aDescription; + getXMLRepresentation(theCmdId.toStdString(), aXmlCfg, aDescription); - return anError; + SessionPtr aMgr = ModelAPI_Session::get(); + aMgr->startOperation(theCmdId.toStdString()); + + ModuleBase_Dialog aDlg(myWorkshop, aXmlCfg); + if (aDlg.exec() == QDialog::Accepted) + aMgr->finishOperation(); + else + aMgr->abortOperation(); + myWorkshop->updateCommandStatus(); } -QString ModuleBase_IModule::getWidgetError(ModuleBase_ModelWidget* theWidget) + +void ModuleBase_IModule::launchOperation(const QString& theCmdId, + const bool& isStartAfterCommitOnly) { - QString anError; + /// selection should be obtained from workshop before ask if the operation can be started as + /// the canStartOperation method performs commit/abort of previous operation. + /// Sometimes commit/abort may cause selection clear(Sketch operation) as a result + /// it will be lost and is not used for preselection. + ModuleBase_ISelection* aSelection = myWorkshop->selection(); + QList aPreSelected = + aSelection->getSelected(ModuleBase_ISelection::AllControls); - if (!theWidget || !theWidget->feature().get()) - return anError; + ModuleBase_OperationFeature* aCurOperation = dynamic_cast + (myWorkshop->currentOperation()); + QString aCurOperationKind = aCurOperation ? aCurOperation->getDescription()->operationId() : ""; - std::string anAttributeID = theWidget->attributeID(); - AttributePtr anAttribute = theWidget->feature()->attribute(anAttributeID); - if (!anAttribute.get()) - return anError; + bool isCommitted; + if (!myWorkshop->canStartOperation(theCmdId, isCommitted)) + return; - std::string aValidatorID; - std::string anErrorMsg; + /// reentrant operation(Sketch Line) should not be started if operation is aborted + if (isStartAfterCommitOnly && !isCommitted) + return; - static ModelAPI_ValidatorsFactory* aValidators = ModelAPI_Session::get()->validators(); - if (!aValidators->validate(anAttribute, aValidatorID, anErrorMsg)) { - if (anErrorMsg.empty()) - anErrorMsg = "unknown error."; - anErrorMsg = anAttributeID + " - " + aValidatorID + ": " + anErrorMsg; + ModuleBase_OperationFeature* aFOperation = dynamic_cast + (createOperation(theCmdId.toStdString())); + if (aFOperation) { + std::shared_ptr aMessage = reentrantMessage(); + if (aMessage.get()) { + setReentrantPreSelection(aMessage); + } + else if (canUsePreselection(aCurOperationKind, theCmdId)) { + // restore of previous opeation is absent or new launched operation has the same kind + aFOperation->initSelection(aPreSelected); + } + workshop()->processLaunchOperation(aFOperation); + + if (aFOperation) { + FeaturePtr aFeature = aFOperation->feature(); + ModelReentrantPtr aReentrantFeature = + std::dynamic_pointer_cast(aFeature); + if (aReentrantFeature.get()) { + if (aMessage.get()) { + ModuleBase_IPropertyPanel* aPanel = workshop()->propertyPanel(); + std::string aPrevAttribute = aReentrantFeature->processEvent(aMessage); + if (!aPrevAttribute.empty()) { + workshop()->errorMgr()->updateActions(aFeature); + ModuleBase_ModelWidget* aPrevWidget = aPanel->modelWidget(aPrevAttribute); + aPanel->activateNextWidget(aPrevWidget); + } + } + } + } } +} + +AISObjectPtr ModuleBase_IModule::createPresentation(const ObjectPtr& theResult) +{ + return AISObjectPtr(); +} - anError = QString::fromStdString(anErrorMsg); - if (anError.isEmpty()) - anError = theWidget->getValueStateError(); +bool ModuleBase_IModule::canBeShaded(Handle(AIS_InteractiveObject) theAIS) const +{ + return true; +} - return anError; +QString ModuleBase_IModule::getFeatureError(const FeaturePtr& theFeature) +{ + // Error already translated. + std::string aMsg = ModelAPI_Tools::getFeatureError(theFeature); + return QString::fromUtf8(aMsg.c_str()); } void ModuleBase_IModule::grantedOperationIds(ModuleBase_Operation* theOperation, @@ -142,11 +187,6 @@ ModuleBase_Operation* ModuleBase_IModule::getNewOperation(const std::string& the return new ModuleBase_OperationFeature(theFeatureId.c_str(), this); } -bool ModuleBase_IModule::customizeObject(ObjectPtr theObject, const bool theUpdateViewer) -{ - return false; -} - ModuleBase_Operation* ModuleBase_IModule::createOperation(const std::string& theFeatureId) { ModuleBase_OperationFeature* aFOperation = dynamic_cast @@ -164,12 +204,8 @@ ModuleBase_Operation* ModuleBase_IModule::createOperation(const std::string& the } } - std::string aPluginFileName = myFeaturesInFiles[theFeatureId]; - Config_WidgetReader aWdgReader = Config_WidgetReader(aPluginFileName); - aWdgReader.readAll(); - std::string aXmlCfg = aWdgReader.featureWidgetCfg(theFeatureId); - std::string aDescription = aWdgReader.featureDescription(theFeatureId); - + std::string aXmlCfg, aDescription; + getXMLRepresentation(theFeatureId, aXmlCfg, aDescription); aFOperation->getDescription()->setDescription(QString::fromStdString(aDescription)); aFOperation->getDescription()->setXmlRepresentation(QString::fromStdString(aXmlCfg)); @@ -179,12 +215,38 @@ ModuleBase_Operation* ModuleBase_IModule::createOperation(const std::string& the void ModuleBase_IModule::createFeatures() { registerValidators(); - registerFilters(); registerProperties(); Config_ModuleReader aXMLReader = Config_ModuleReader(); aXMLReader.readAll(); myFeaturesInFiles = aXMLReader.featuresInFiles(); + myProprietaryFeatures = aXMLReader.proprietaryFeatures(); + myProprietaryPlugins = aXMLReader.proprietaryPlugins(); +} + +void ModuleBase_IModule::processProprietaryFeatures() +{ + std::set::iterator it = myFeaturesValidLicense.begin(); + while (it != myFeaturesValidLicense.end()) { + std::map::iterator aFound = myProprietaryFeatures.find(*it); + if (aFound == myProprietaryFeatures.end()) + ++it; + else { + myFeaturesInFiles[aFound->first] = aFound->second; + myProprietaryFeatures.erase(aFound); + std::set::iterator aRemoveIt = it++; + myFeaturesValidLicense.erase(aRemoveIt); + } + } +} + +void ModuleBase_IModule::loadProprietaryPlugins() +{ + for (std::set::const_iterator itP = myProprietaryPlugins.begin(); + itP != myProprietaryPlugins.end(); ++itP) { + if (!ModelAPI_Session::get()->checkLicense(*itP)) + Events_InfoMessage(*itP, "License of %1 plugin is not valid or not exist!").arg(*itP).send(); + } } @@ -203,6 +265,23 @@ bool ModuleBase_IModule::canDisplayObject(const ObjectPtr& theObject) const return true; } +bool ModuleBase_IModule::canUsePreselection(const QString& thePreviousOperationKind, + const QString& theStartedOperationKind) +{ + // no previous operation + if (thePreviousOperationKind.isEmpty()) + return true; + // edit operation + if (thePreviousOperationKind.endsWith(ModuleBase_OperationFeature::EditSuffix())) + return true; + + // reentrant operation + if (thePreviousOperationKind == theStartedOperationKind) + return true; + + return false; +} + bool ModuleBase_IModule::canUndo() const { SessionPtr aMgr = ModelAPI_Session::get(); @@ -221,29 +300,37 @@ void ModuleBase_IModule::onFeatureTriggered() //Do nothing on uncheck if (aCmd->isCheckable() && !aCmd->isChecked()) { ModuleBase_Operation* anOperation = myWorkshop->findStartedOperation(aCmd->data().toString()); - if (myWorkshop->canStopOperation(anOperation)) - myWorkshop->abortOperation(anOperation); + if (myWorkshop->canStopOperation(anOperation)) { + bool isCommitted; + myWorkshop->stopOperation(anOperation, isCommitted); + } else { aCmd->setChecked(true); } } else { - launchOperation(aCmd->data().toString()); - emit operationLaunched(); + QString aCmdId = aCmd->data().toString(); + std::shared_ptr aInfo = myWorkshop->featureInfo(aCmdId); + if (aInfo.get() && aInfo->isModal()) { + launchModal(aCmdId); + } else { + launchOperation(aCmdId, false); + } } } void ModuleBase_IModule::editFeature(FeaturePtr theFeature) { std::string aFeatureId = theFeature->getKind(); - if (!myWorkshop->canStartOperation(aFeatureId.c_str())) + bool isCommitted; + if (!myWorkshop->canStartOperation(aFeatureId.c_str(), isCommitted)) return; ModuleBase_OperationFeature* aFOperation = dynamic_cast (createOperation(aFeatureId)); if (aFOperation) { aFOperation->setFeature(theFeature); - sendOperation(aFOperation); + workshop()->processLaunchOperation(aFOperation); } } @@ -254,7 +341,50 @@ bool ModuleBase_IModule::canActivateSelection(const ObjectPtr& theObject) const return !aFOperation || !aFOperation->hasObject(theObject); } -void ModuleBase_IModule::operationResumed(ModuleBase_Operation* theOperation) +void ModuleBase_IModule::operationResumed(ModuleBase_Operation* theOperation) { emit resumed(theOperation); } + +void ModuleBase_IModule::getXMLRepresentation(const std::string& theFeatureId, + std::string& theXmlCfg, std::string& theDescription) +{ + std::string aPluginFileName = myFeaturesInFiles[theFeatureId]; + Config_WidgetReader aWdgReader = Config_WidgetReader(aPluginFileName); + aWdgReader.readAll(); + + theXmlCfg = aWdgReader.featureWidgetCfg(theFeatureId); + theDescription = aWdgReader.featureDescription(theFeatureId); +} + + +//****************************************************** +QIntList ModuleBase_IModule::selectionFilters() +{ + QIntList aTypes; + + std::map::const_iterator aFiltersIt = + mySelectionFilters.begin(); + for (; aFiltersIt != mySelectionFilters.end(); aFiltersIt++) + aTypes.append(aFiltersIt->first); + + return aTypes; +} + +//****************************************************** +void ModuleBase_IModule::registerSelectionFilter(const ModuleBase_SelectionFilterType theFilterType, + const Handle(SelectMgr_Filter)& theFilter) +{ + mySelectionFilters[theFilterType] = theFilter; +} + +//****************************************************** +Handle(SelectMgr_Filter) ModuleBase_IModule::selectionFilter(const int theType) +{ + ModuleBase_SelectionFilterType aType = (ModuleBase_SelectionFilterType)theType; + + if (mySelectionFilters.find(aType) != mySelectionFilters.end()) + return mySelectionFilters[aType]; + else + return Handle(SelectMgr_Filter)(); +}