From f9b192f852b0e67b44cf1b6c38b639eff10b3509 Mon Sep 17 00:00:00 2001 From: mpv Date: Tue, 17 Mar 2015 14:07:28 +0300 Subject: [PATCH] Make undo/redo working correctly with the color of results --- src/Model/Model_AttributeIntArray.cpp | 6 ++- src/Model/Model_Document.cpp | 57 +++++++++++++------------ src/ModelAPI/ModelAPI_Object.h | 1 - src/ModelAPI/ModelAPI_Result.cpp | 12 ++++++ src/ModelAPI/ModelAPI_Result.h | 4 ++ src/ModuleBase/ModuleBase_Operation.cpp | 9 +--- src/ModuleBase/ModuleBase_Operation.h | 3 -- src/XGUI/XGUI_Workshop.cpp | 2 - 8 files changed, 50 insertions(+), 44 deletions(-) diff --git a/src/Model/Model_AttributeIntArray.cpp b/src/Model/Model_AttributeIntArray.cpp index 8f21a427d..2d061d411 100644 --- a/src/Model/Model_AttributeIntArray.cpp +++ b/src/Model/Model_AttributeIntArray.cpp @@ -20,12 +20,14 @@ int Model_AttributeIntArray::size() { - return myArray.IsNull() ? 0 : myArray->Length(); + // checking the validity because attribute (as a field) may be presented, + // but without label: it is undoed + return (myArray.IsNull() || !myArray->IsValid()) ? 0 : myArray->Length(); } void Model_AttributeIntArray::setSize(const int theSize) { - if (myArray.IsNull()) { // create array if it is not done yet + if (myArray.IsNull() || !myArray->IsValid()) { // create array if it is not done yet if (theSize != 0) { // if size is zero, nothing to do (null array means there is no array) myArray = TDataStd_IntegerArray::Set(myLab, 0, theSize); owner()->data()->sendAttributeUpdated(this); diff --git a/src/Model/Model_Document.cpp b/src/Model/Model_Document.cpp index 8f4ac4cb1..184604537 100644 --- a/src/Model/Model_Document.cpp +++ b/src/Model/Model_Document.cpp @@ -923,6 +923,12 @@ void Model_Document::synchronizeFeatures(const bool theMarkUpdated, const bool t Model_Application::getApplication()->getDocument(myID); // after all updates, sends a message that groups of features were created or updated Events_Loop* aLoop = Events_Loop::loop(); + static Events_ID aDispEvent = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY); + static Events_ID aCreateEvent = Events_Loop::eventByName(EVENT_OBJECT_CREATED); + static Events_ID anUpdateEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED); + static Events_ID aRedispEvent = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY); + static Events_ID aDeleteEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED); + static Events_ID aToHideEvent = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY); aLoop->activateFlushes(false); // update all objects by checking are they of labels or not @@ -934,8 +940,8 @@ void Model_Document::synchronizeFeatures(const bool theMarkUpdated, const bool t if (!myObjs.IsBound(aFeatureLabel)) { // a new feature is inserted // create a feature aFeature = ModelAPI_Session::get()->createFeature( - TCollection_AsciiString(Handle(TDataStd_Comment)::DownCast(aLabIter.Value())->Get()) - .ToCString()); + TCollection_AsciiString(Handle(TDataStd_Comment)::DownCast(aLabIter.Value())->Get()) + .ToCString()); if (!aFeature) { // somethig is wrong, most probably, the opened document has invalid structure Events_Error::send("Invalid type of object in the document"); aLabIter.Value()->Label().ForgetAllAttributes(); @@ -947,18 +953,16 @@ void Model_Document::synchronizeFeatures(const bool theMarkUpdated, const bool t initData(aFeature, aFeatureLabel, TAG_FEATURE_ARGUMENTS); // event: model is updated - static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_CREATED); - ModelAPI_EventCreator::get()->sendUpdated(aFeature, anEvent); + ModelAPI_EventCreator::get()->sendUpdated(aFeature, aCreateEvent); } else { // nothing is changed, both iterators are incremented aFeature = myObjs.Find(aFeatureLabel); aKeptFeatures.insert(aFeature); if (theMarkUpdated) { - static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED); - ModelAPI_EventCreator::get()->sendUpdated(aFeature, anEvent); + ModelAPI_EventCreator::get()->sendUpdated(aFeature, anUpdateEvent); } } } - // update results of thefeatures (after features created because they may be connected, like sketch and sub elements) + // update results of the features (after features created because they may be connected, like sketch and sub elements) std::list aComposites; // composites must be updated after their subs (issue 360) TDF_ChildIDIterator aLabIter2(featuresLabel(), TDataStd_Comment::GetID()); for (; aLabIter2.More(); aLabIter2.Next()) { @@ -979,23 +983,20 @@ void Model_Document::synchronizeFeatures(const bool theMarkUpdated, const bool t NCollection_DataMap::Iterator aFIter(myObjs); while (aFIter.More()) { if (aKeptFeatures.find(aFIter.Value()) == aKeptFeatures.end() - && aNewFeatures.find(aFIter.Value()) == aNewFeatures.end()) { - FeaturePtr aFeature = aFIter.Value(); - // event: model is updated - //if (aFeature->isInHistory()) { + && aNewFeatures.find(aFIter.Value()) == aNewFeatures.end()) { + FeaturePtr aFeature = aFIter.Value(); + // event: model is updated + //if (aFeature->isInHistory()) { ModelAPI_EventCreator::get()->sendDeleted(aThis, ModelAPI_Feature::group()); - //} - // results of this feature must be redisplayed (hided) - static Events_ID EVENT_DISP = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY); - const std::list >& aResults = aFeature->results(); - std::list >::const_iterator aRIter = aResults.begin(); - // redisplay also removed feature (used for sketch and AISObject) - ModelAPI_EventCreator::get()->sendUpdated(aFeature, EVENT_DISP); - aFeature->erase(); - // unbind after the "erase" call: on abort sketch is removes sub-objects that corrupts aFIter - myObjs.UnBind(aFIter.Key()); - // reinitialize iterator because unbind may corrupt the previous order in the map - aFIter.Initialize(myObjs); + //} + // results of this feature must be redisplayed (hided) + // redisplay also removed feature (used for sketch and AISObject) + ModelAPI_EventCreator::get()->sendUpdated(aFeature, aRedispEvent); + aFeature->erase(); + // unbind after the "erase" call: on abort sketch is removes sub-objects that corrupts aFIter + myObjs.UnBind(aFIter.Key()); + // reinitialize iterator because unbind may corrupt the previous order in the map + aFIter.Initialize(myObjs); } else aFIter.Next(); } @@ -1007,11 +1008,11 @@ void Model_Document::synchronizeFeatures(const bool theMarkUpdated, const bool t myExecuteFeatures = false; aLoop->activateFlushes(true); - aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED)); - aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_DELETED)); - aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED)); - aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY)); - aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_TOHIDE)); + aLoop->flush(aCreateEvent); + aLoop->flush(aDeleteEvent); + aLoop->flush(anUpdateEvent); + aLoop->flush(aRedispEvent); + aLoop->flush(aToHideEvent); myExecuteFeatures = true; } diff --git a/src/ModelAPI/ModelAPI_Object.h b/src/ModelAPI/ModelAPI_Object.h index 6abadf9ea..f04d10ad5 100644 --- a/src/ModelAPI/ModelAPI_Object.h +++ b/src/ModelAPI/ModelAPI_Object.h @@ -56,7 +56,6 @@ class ModelAPI_Object /// Called on change of any argument-attribute of this object /// \param theID identifier of changed attribute - // MODELAPI_EXPORT MODELAPI_EXPORT virtual void attributeChanged(const std::string& theID); /// Initializes the default states of the object diff --git a/src/ModelAPI/ModelAPI_Result.cpp b/src/ModelAPI/ModelAPI_Result.cpp index aa5ddd227..d43592014 100644 --- a/src/ModelAPI/ModelAPI_Result.cpp +++ b/src/ModelAPI/ModelAPI_Result.cpp @@ -5,6 +5,10 @@ // Author: Mikhail PONIKAROV #include "ModelAPI_Result.h" +#include +#include +#include +#include ModelAPI_Result::~ModelAPI_Result() { @@ -15,3 +19,11 @@ std::shared_ptr ModelAPI_Result::shape() { return std::shared_ptr(); } + +void ModelAPI_Result::attributeChanged(const std::string& theID) +{ + 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(); + aECreator->sendUpdated(data()->attribute(theID)->owner(), EVENT_DISP); +} diff --git a/src/ModelAPI/ModelAPI_Result.h b/src/ModelAPI/ModelAPI_Result.h index c02abf608..daad432e7 100644 --- a/src/ModelAPI/ModelAPI_Result.h +++ b/src/ModelAPI/ModelAPI_Result.h @@ -53,6 +53,10 @@ class ModelAPI_Result : public ModelAPI_Object /// Returns the shape-result produced by this feature (or null if no shapes) MODELAPI_EXPORT virtual std::shared_ptr shape(); + + /// On change of attribute of the result update presentation of this result: + /// for the current moment there are only presentation attributes assigned to results + MODELAPI_EXPORT virtual void attributeChanged(const std::string& theID); }; //! Pointer on feature object diff --git a/src/ModuleBase/ModuleBase_Operation.cpp b/src/ModuleBase/ModuleBase_Operation.cpp index 6119c42c8..4b8c7d34b 100644 --- a/src/ModuleBase/ModuleBase_Operation.cpp +++ b/src/ModuleBase/ModuleBase_Operation.cpp @@ -85,7 +85,7 @@ FeaturePtr ModuleBase_Operation::createFeature(const bool theFlushMessage) if (myParentFeature.get()) { myFeature = myParentFeature->addFeature(getDescription()->operationId().toStdString()); } else { - std::shared_ptr aDoc = document(); + std::shared_ptr aDoc = ModelAPI_Session::get()->activeDocument(); myFeature = aDoc->addFeature(getDescription()->operationId().toStdString()); } if (myFeature) { // TODO: generate an error if feature was not created @@ -127,13 +127,6 @@ bool ModuleBase_Operation::hasObject(ObjectPtr theObj) const return false; } - -std::shared_ptr ModuleBase_Operation::document() const -{ - return ModelAPI_Session::get()->moduleDocument(); -} - - void ModuleBase_Operation::start() { QString anId = getDescription()->operationId(); diff --git a/src/ModuleBase/ModuleBase_Operation.h b/src/ModuleBase/ModuleBase_Operation.h index 45082511a..a76c7c0ee 100644 --- a/src/ModuleBase/ModuleBase_Operation.h +++ b/src/ModuleBase/ModuleBase_Operation.h @@ -219,9 +219,6 @@ signals: /// \return Returns TRUE if current operation can be committed, e.g. all parameters are filled virtual bool canBeCommitted() const; - /// Returns pointer to the root document. - std::shared_ptr document() const; - /// Return a widget value point by the selection and the viewer position /// The default realization returns false /// \param thePrs the presentation diff --git a/src/XGUI/XGUI_Workshop.cpp b/src/XGUI/XGUI_Workshop.cpp index dc5436749..6100b9ecf 100644 --- a/src/XGUI/XGUI_Workshop.cpp +++ b/src/XGUI/XGUI_Workshop.cpp @@ -1461,7 +1461,6 @@ void XGUI_Workshop::changeColor(const QObjectPtrList& theObjects) } // 4. set the value to all results - static Events_ID EVENT_DISP = Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY); AttributeIntArrayPtr aColorAttr; foreach(ObjectPtr anObj, theObjects) { ResultPtr aResult = std::dynamic_pointer_cast(anObj); @@ -1474,7 +1473,6 @@ void XGUI_Workshop::changeColor(const QObjectPtrList& theObjects) aColorAttr->setValue(0, aRedResult); aColorAttr->setValue(1, aGreenResult); aColorAttr->setValue(2, aBlueResult); - ModelAPI_EventCreator::get()->sendUpdated(anObj, EVENT_DISP); } } } -- 2.39.2