Salome HOME
Make undo/redo working correctly with the color of results
authormpv <mpv@opencascade.com>
Tue, 17 Mar 2015 11:07:28 +0000 (14:07 +0300)
committermpv <mpv@opencascade.com>
Tue, 17 Mar 2015 11:07:28 +0000 (14:07 +0300)
src/Model/Model_AttributeIntArray.cpp
src/Model/Model_Document.cpp
src/ModelAPI/ModelAPI_Object.h
src/ModelAPI/ModelAPI_Result.cpp
src/ModelAPI/ModelAPI_Result.h
src/ModuleBase/ModuleBase_Operation.cpp
src/ModuleBase/ModuleBase_Operation.h
src/XGUI/XGUI_Workshop.cpp

index 8f21a427dcc2f437a7573fd57022d1c15e690fd9..2d061d411472c02ef5079f461d054c3e46f34a0a 100644 (file)
 
 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);
index 8f4ac4cb17ef7eb62a3dc7ee4db6b4bcd8e64802..1846045379e64f5aab250cc435c741240d53b705 100644 (file)
@@ -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<FeaturePtr> 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<TDF_Label, FeaturePtr>::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<std::shared_ptr<ModelAPI_Result> >& aResults = aFeature->results();
-      std::list<std::shared_ptr<ModelAPI_Result> >::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;
 }
 
index 6abadf9eae52ddd84ac98a2816e9493c2f1f239c..f04d10ad5da5c417579b140e78188980c76d471c 100644 (file)
@@ -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
index aa5ddd227c9933c95e37adfd09c0c5195d1f18aa..d435920149f5dc4e44a33c7421caae8750c59771 100644 (file)
@@ -5,6 +5,10 @@
 // Author:      Mikhail PONIKAROV
 
 #include "ModelAPI_Result.h"
+#include <ModelAPI_Events.h>
+#include <ModelAPI_Data.h>
+#include <ModelAPI_Attribute.h>
+#include <Events_Loop.h>
 
 ModelAPI_Result::~ModelAPI_Result()
 {
@@ -15,3 +19,11 @@ std::shared_ptr<GeomAPI_Shape> ModelAPI_Result::shape()
 {
   return std::shared_ptr<GeomAPI_Shape>();
 }
+
+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);
+}
index c02abf60828854ffb8dac14a4c808e9129173efd..daad432e75dbdc2de59a1b42c977bc982d342d0a 100644 (file)
@@ -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<GeomAPI_Shape> 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
index 6119c42c80fd91df36bb17afca727d12cfeb861f..4b8c7d34bec1db0259ad11036dc3dffed806e207 100644 (file)
@@ -85,7 +85,7 @@ FeaturePtr ModuleBase_Operation::createFeature(const bool theFlushMessage)
   if (myParentFeature.get()) {
     myFeature = myParentFeature->addFeature(getDescription()->operationId().toStdString());
   } else {
-    std::shared_ptr<ModelAPI_Document> aDoc = document();
+    std::shared_ptr<ModelAPI_Document> 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<ModelAPI_Document> ModuleBase_Operation::document() const
-{
-  return ModelAPI_Session::get()->moduleDocument();
-}
-
-
 void ModuleBase_Operation::start()
 {
   QString anId = getDescription()->operationId();
index 45082511a531d80517adc94f349eb95f16d53784..a76c7c0ee7c356ec519a5e97f1ac25046fec4c2f 100644 (file)
@@ -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<ModelAPI_Document> document() const;
-
   /// Return a widget value point by the selection and the viewer position
   /// The default realization returns false
   /// \param thePrs the presentation
index dc54367498b68b55918a8c871eed80dad398fe47..6100b9ecf43cc37efde993545ed6e9db1067a45d 100644 (file)
@@ -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<ModelAPI_Result>(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);
       }
     }
   }