X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FModelAPI%2FModelAPI_Feature.cpp;h=4b0939fab5e3220691f8928583537a9f76fd6d41;hb=c0e273c1479a9940dbe4f966853c82a6b8709d88;hp=65cfa361ed3e8645cbf3812d45a90d83f5e31f68;hpb=7bf19255421b34594c7b0a76d0ce28166d0ce895;p=modules%2Fshaper.git diff --git a/src/ModelAPI/ModelAPI_Feature.cpp b/src/ModelAPI/ModelAPI_Feature.cpp index 65cfa361e..4b0939fab 100644 --- a/src/ModelAPI/ModelAPI_Feature.cpp +++ b/src/ModelAPI/ModelAPI_Feature.cpp @@ -1,8 +1,21 @@ -// Copyright (C) 2014-20xx CEA/DEN, EDF R&D - -// File: ModelAPI_Feature.cpp -// Created: 17 Jul 2014 -// Author: Mikhail PONIKAROV +// Copyright (C) 2014-2022 CEA/DEN, EDF R&D +// +// 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_Feature.h" #include @@ -10,14 +23,27 @@ #include #include #include +#include +#include #include +#include +#include + +void ModelAPI_Feature::setError(const std::string& theError, + bool isSend, + bool isTranslate) +{ + std::string anError = isTranslate ? Config_Translator::translate(getKind(), theError) + : theError; + data()->setError(anError, isSend); +} const std::list >& ModelAPI_Feature::results() { return myResults; } -std::shared_ptr ModelAPI_Feature::firstResult() +std::shared_ptr ModelAPI_Feature::firstResult() const { return myResults.empty() ? std::shared_ptr() : *(myResults.begin()); } @@ -29,22 +55,31 @@ std::shared_ptr ModelAPI_Feature::lastResult() void ModelAPI_Feature::setResult(const std::shared_ptr& theResult) { - if (firstResult() == theResult) { // just updated - static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED); - ModelAPI_EventCreator::get()->sendUpdated(theResult, anEvent); - return; - } - // created - while (!myResults.empty()) { // remove one by one with messages - std::shared_ptr aRes = *(myResults.begin()); - myResults.erase(myResults.begin()); - ModelAPI_EventCreator::get()->sendDeleted(aRes->document(), aRes->groupName()); + static Events_ID EVENT_UPD = Events_Loop::eventByName(EVENT_OBJECT_UPDATED); + static const ModelAPI_EventCreator* aECreator = ModelAPI_EventCreator::get(); + + if (firstResult() == theResult) { + // nothing to change + } else if (!myResults.empty()) { // all except first become disabled + std::list >::iterator aResIter = myResults.begin(); + *aResIter = theResult; + aECreator->sendUpdated(theResult, EVENT_UPD); + for(aResIter++; aResIter != myResults.end(); aResIter++) { + (*aResIter)->setDisabled((*aResIter), true); + } + } else { + myResults.push_back(theResult); } - myResults.push_back(theResult); - static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_CREATED); - ModelAPI_EventCreator::get()->sendUpdated(theResult, anEvent); - // Create event for first Feature - Events_Loop::loop()->flush(anEvent); + // in any case result becomes enabled + if (!isDisabled()) // disabled feature may be executed when it is added as not enabled (#2078) + theResult->setDisabled(theResult, false); + + if (Config_PropManager::getAutoColorStatus() + && theResult->groupName() == ModelAPI_ResultGroup::group()) { + std::vector aColor; + ModelAPI_Tools::findRandomColor(aColor); + ModelAPI_Tools::setColor(theResult, aColor); + } } void ModelAPI_Feature::setResult(const std::shared_ptr& theResult, @@ -56,82 +91,96 @@ void ModelAPI_Feature::setResult(const std::shared_ptr& theResu } if (aResIter == myResults.end()) { // append myResults.push_back(theResult); - static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_CREATED); - ModelAPI_EventCreator::get()->sendUpdated(theResult, anEvent); - // Create event for first Feature, send it to make "created" earlier than "updated" - // VSV: Commenting out of this statement causes problems with circle operation for example - Events_Loop::loop()->flush(anEvent); } else { // update *aResIter = theResult; - static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED); - ModelAPI_EventCreator::get()->sendUpdated(theResult, anEvent); } + theResult->setDisabled(theResult, false); } -void ModelAPI_Feature::removeResult(const std::shared_ptr& theResult) +void ModelAPI_Feature::eraseResultFromList(const std::shared_ptr& theResult) { std::list >::iterator aResIter = myResults.begin(); for(; aResIter != myResults.end(); aResIter++) { ResultPtr aRes = *aResIter; if (aRes == theResult) { std::string aGroup = aRes->groupName(); + aRes->setDisabled(aRes, true); // for complex results to disable all subs aRes->data()->erase(); myResults.erase(aResIter); - static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_DELETED); static Events_Loop* aLoop = Events_Loop::loop(); static Events_ID EVENT_DISP = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY); static const ModelAPI_EventCreator* aECreator = ModelAPI_EventCreator::get(); - ModelAPI_EventCreator::get()->sendDeleted(document(), aGroup); + aECreator->sendDeleted(document(), aGroup); aECreator->sendUpdated(aRes, EVENT_DISP); break; } } } -void ModelAPI_Feature::eraseResults() +void ModelAPI_Feature::removeResults( + const int theSinceIndex, const bool theForever, const bool theFlush) { - if (!myResults.empty()) { - static Events_Loop* aLoop = Events_Loop::loop(); - static Events_ID EVENT_DISP = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY); - static const ModelAPI_EventCreator* aECreator = ModelAPI_EventCreator::get(); + std::list >::iterator aResIter = myResults.begin(); + for(int anIndex = 0; anIndex < theSinceIndex && aResIter != myResults.end(); anIndex++) + aResIter++; - std::list >::iterator aResIter = myResults.begin(); - for(; aResIter != myResults.end(); aResIter++) { - (*aResIter)->data()->erase(); - ModelAPI_EventCreator::get()->sendDeleted(document(), (*aResIter)->groupName()); - aECreator->sendUpdated(*aResIter, EVENT_DISP); + std::string aGroup; + std::list >::iterator aNextIter = aResIter; + while( aNextIter != myResults.end()) { + aGroup = (*aNextIter)->groupName(); + // remove previously erased results: to enable later if needed only actual (of history change) + (*aNextIter)->setDisabled(*aNextIter, true); // just disable results + if (theForever) { + aNextIter = myResults.erase(aNextIter); + } else { + aNextIter++; } - myResults.clear(); - // flush it to avoid left presentations after input of invalid arguments (radius=0) - static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_DELETED); - Events_Loop::loop()->flush(anEvent); } + if (!aGroup.empty() && theFlush) { + // flush visualization changes + static Events_Loop* aLoop = Events_Loop::loop(); + static Events_ID aRedispEvent = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY); + aLoop->flush(aRedispEvent); + static Events_ID aDelEvent = aLoop->eventByName(EVENT_OBJECT_DELETED); + aLoop->flush(aDelEvent); + } +} + +void ModelAPI_Feature::eraseResults(const bool theForever) +{ + removeResults(0, theForever, true); } -std::shared_ptr ModelAPI_Feature::documentToAdd() +const std::string& ModelAPI_Feature::documentToAdd() { - return ModelAPI_Session::get()->activeDocument(); + // empty to use the current document + static const std::string anEmpty; + return anEmpty; } void ModelAPI_Feature::erase() { - static Events_Loop* aLoop = Events_Loop::loop(); - static Events_ID EVENT_DISP = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY); - static const ModelAPI_EventCreator* aECreator = ModelAPI_EventCreator::get(); + // if this is the current feature, make the upper feature as current before removing + if (document().get() && document()->currentFeature(false).get() == this) { + document()->setCurrentFeatureUp(); + } while (!myResults.empty()) { // remove one by one with messages std::shared_ptr aRes = *(myResults.begin()); - myResults.erase(myResults.begin()); - aECreator->sendDeleted(aRes->document(), aRes->groupName()); - aECreator->sendUpdated(aRes, EVENT_DISP); + aRes->setDisabled(aRes, true); // to avoid activation of the Part result + if (!myResults.empty()) {// disabling result may erase the list (on undo of Part, issue 665) + myResults.erase(myResults.begin()); + aRes->erase(); + } } ModelAPI_Object::erase(); } ModelAPI_Feature::~ModelAPI_Feature() { - erase(); + if (data() && data()->isValid()) + erase(); } FeaturePtr ModelAPI_Feature::feature(ObjectPtr theObject) @@ -146,3 +195,76 @@ FeaturePtr ModelAPI_Feature::feature(ObjectPtr theObject) } return aFeature; } + +bool ModelAPI_Feature::isMacro() const +{ + return false; +} + +bool ModelAPI_Feature::setDisabled(const bool theFlag) +{ + if (myIsDisabled != theFlag) { + myIsDisabled = theFlag; + if (myIsDisabled) { + removeResults(0, false, false); // flush will be in setCurrentFeature + } else { + // enable all disabled previously results + std::list >::iterator aResIter = myResults.begin(); + for(; aResIter != myResults.end(); aResIter++) { + (*aResIter)->setDisabled(*aResIter, false); + } + // update selection for the case something was updated higher in the history + // while this feature was disabled, but avoid flushing it immediately and + // wait while all the previous features update myIsDisabled flag + // (flush will be called by the document) + static Events_Loop* aLoop = Events_Loop::loop(); + static Events_ID kUpdatedSel = aLoop->eventByName(EVENT_UPDATE_SELECTION); + static const ModelAPI_EventCreator* aECreator = ModelAPI_EventCreator::get(); + aECreator->sendUpdated(data()->owner(), kUpdatedSel, true); + } + return true; + } + return false; +} + +bool ModelAPI_Feature::isDisabled() +{ + return myIsDisabled; +} + +// LCOV_EXCL_START +bool ModelAPI_Feature::setStable(const bool theFlag) +{ + if (myIsStable != theFlag) { + myIsStable = theFlag; + // send an event about the stability change (editing is started/finished) + static Events_Loop* aLoop = Events_Loop::loop(); + static Events_ID EVENT_STAB = aLoop->eventByName(EVENT_STABILITY_CHANGED); + std::shared_ptr aMessage(new Events_Message(EVENT_STAB, this)); + aLoop->send(aMessage, false); + return true; + } + return false; +} +// LCOV_EXCL_STOP + +bool ModelAPI_Feature::isStable() +{ + return myIsStable; +} + +bool ModelAPI_Feature::customAction(const std::string& /*theActionId*/) +{ + return false; +} + +bool ModelAPI_Feature::isPreviewNeeded() const +{ + return true; +} + +void ModelAPI_Feature::init() +{ + myIsDisabled = false; + myIsStable = true; +}