]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Initial implementation of working with history: issue #499
authormpv <mpv@opencascade.com>
Fri, 8 May 2015 09:01:58 +0000 (12:01 +0300)
committermpv <mpv@opencascade.com>
Fri, 8 May 2015 09:01:58 +0000 (12:01 +0300)
src/Model/Model_Document.cpp
src/Model/Model_Document.h
src/ModelAPI/ModelAPI_Document.h
src/ModelAPI/ModelAPI_Feature.cpp
src/ModelAPI/ModelAPI_Feature.h

index 0535ef7f206f3a1900186e2bc393123ce383286b..7ddc7dcfde3db46ab5182075648418b7214418d3 100644 (file)
@@ -49,6 +49,9 @@ static const int TAG_GENERAL = 1;  // general properties tag
 static const int TAG_OBJECTS = 2;  // tag of the objects sub-tree (features, results)
 static const int TAG_HISTORY = 3;  // tag of the history sub-tree (python dump)
 
+// general sub-labels
+static const int TAG_CURRENT_FEATURE = 1; ///< where the reference to the current feature label is located (or no attribute if null feature)
+
 // feature sub-labels
 static const int TAG_FEATURE_ARGUMENTS = 1;  ///< where the arguments are located
 static const int TAG_FEATURE_RESULTS = 2;  ///< where the results are located
@@ -596,6 +599,7 @@ FeaturePtr Model_Document::addFeature(std::string theID)
       // event: feature is added
       static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_CREATED);
       ModelAPI_EventCreator::get()->sendUpdated(aFeature, anEvent);
+      setCurrentFeature(aFeature); // after all this feature stays in the document, so make it current
     } else { // feature must be executed
        // no creation event => updater not working, problem with remove part
       aFeature->execute();
@@ -697,6 +701,14 @@ void Model_Document::removeFeature(FeaturePtr theFeature/*, const bool theCheck*
         aComposite->removeFeature(theFeature);
       }
     }
+    // if this feature is current, make the current the previous feature
+    if (theFeature == currentFeature()) {
+      int aCurrentIndex = index(theFeature);
+      if (aCurrentIndex != -1) {
+        setCurrentFeature(std::dynamic_pointer_cast<ModelAPI_Feature>(
+          object(ModelAPI_Feature::group(), aCurrentIndex - 1)));
+      }
+    }
 
     // erase fields
     theFeature->erase();
@@ -952,11 +964,60 @@ int Model_Document::size(const std::string& theGroupID, const bool theHidden)
   return aResult;
 }
 
+std::shared_ptr<ModelAPI_Feature> Model_Document::currentFeature()
+{
+  static TDF_Label aRefLab = generalLabel().FindChild(TAG_CURRENT_FEATURE);
+  Handle(TDF_Reference) aRef;
+  if (aRefLab.FindAttribute(TDF_Reference::GetID(), aRef)) {
+    return feature(aRef->Get());
+  }
+  return std::shared_ptr<ModelAPI_Feature>(); // null feature means the higher than first
+}
+
+void Model_Document::setCurrentFeature(std::shared_ptr<ModelAPI_Feature> theCurrent)
+{
+  static TDF_Label aRefLab = generalLabel().FindChild(TAG_CURRENT_FEATURE);
+  if (theCurrent.get()) {
+    std::shared_ptr<Model_Data> aData = std::static_pointer_cast<Model_Data>(theCurrent->data());
+    if (aData.get()) {
+      TDF_Label aFeatureLabel = aData->label().Father();
+      Handle(TDF_Reference) aRef;
+      if (aRefLab.FindAttribute(TDF_Reference::GetID(), aRef)) {
+        aRef->Set(aFeatureLabel);
+      } else {
+        aRef = TDF_Reference::Set(aRefLab, aFeatureLabel);
+      }
+    }
+  } else { // remove reference for the null feature
+    aRefLab.ForgetAttribute(TDF_Reference::GetID());
+  }
+  // make all features after this feature disabled in reversed order (to remove results without deps)
+  bool aPassed = false; // flag that the current object is already passed in cycle
+  int aSize = size(ModelAPI_Feature::group(), true);
+  for(int a = aSize - 1; a >= 0; a--) {
+    FeaturePtr aFeature = 
+      std::dynamic_pointer_cast<ModelAPI_Feature>(object(ModelAPI_Feature::group(), a, true));
+    if (aFeature->setDisabled(!aPassed)) {
+      // state of feature is changed => so feature become updated
+      static Events_ID anUpdateEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED);
+      ModelAPI_EventCreator::get()->sendUpdated(aFeature, anUpdateEvent);
+
+    }
+    // check this only after passed become enabled: the current feature is enabled!
+    if (aFeature == theCurrent) aPassed = true;
+  }
+}
+
 TDF_Label Model_Document::featuresLabel() const
 {
   return myDoc->Main().FindChild(TAG_OBJECTS);
 }
 
+TDF_Label Model_Document::generalLabel() const
+{
+  return myDoc->Main().FindChild(TAG_GENERAL);
+}
+
 void Model_Document::setUniqueName(FeaturePtr theFeature)
 {
   if (!theFeature->data()->name().empty())
index a307e77966ac7406efbdbeb4ab63295ef56d2ad5..17c14caa9d008bbd060fd664a3a6570b2d63d0be 100644 (file)
@@ -134,6 +134,15 @@ class Model_Document : public ModelAPI_Document
   //! If theHidden is true, it counts also the features that are not in tree
   MODEL_EXPORT virtual int size(const std::string& theGroupID, const bool theHidden = false);
 
+  //! Returns the feature that is currently edited in this document, normally
+  //! this is the latest created feature
+  //! \returns null if next created feature must be the first
+  MODEL_EXPORT virtual std::shared_ptr<ModelAPI_Feature> currentFeature();
+
+  //! Sets the current feature: all features below will be disabled, new features
+  //! will be appended after this one.
+  MODEL_EXPORT virtual void setCurrentFeature(std::shared_ptr<ModelAPI_Feature> theCurrent);
+
   /// Creates a construction cresults
   MODEL_EXPORT virtual std::shared_ptr<ModelAPI_ResultConstruction> createConstruction(
       const std::shared_ptr<ModelAPI_Data>& theFeatureData, const int theIndex = 0);
@@ -170,6 +179,8 @@ class Model_Document : public ModelAPI_Document
 
   //! Returns (creates if needed) the features label
   TDF_Label featuresLabel() const;
+  //! Returns (creates if needed) the general label
+  TDF_Label generalLabel() const;
 
   //! Initializes feature with a unique name in this group (unique name is generated as 
   //! feature type + "_" + index
index 9fe19db6675d1c287a184dfbc8741651ec2ecd5f..dc43fac414cfa9ec0bfedbaee65c5f225c317394 100644 (file)
@@ -88,6 +88,15 @@ public:
   //! If theHidden is true, it counts also the features that are not in tree
   virtual int size(const std::string& theGroupID, const bool theHidden = false) = 0;
 
+  //! Returns the feature that is currently edited in this document, normally
+  //! this is the latest created feature
+  //! \returns null if next created feature must be the first
+  virtual std::shared_ptr<ModelAPI_Feature> currentFeature() = 0;
+
+  //! Sets the current feature: all features below will be disabled, new features
+  //! will be appended after this one.
+  virtual void setCurrentFeature(std::shared_ptr<ModelAPI_Feature> theCurrent) = 0;
+
   /// To virtually destroy the fields of successors
   MODELAPI_EXPORT virtual ~ModelAPI_Document();
 
index 8a5d93cbdc04eee1933bc77bb1c1be2ba9dfc6f6..1a756e2d8a3112c3d3e812a0676bc3070deb8433 100644 (file)
@@ -177,3 +177,19 @@ bool ModelAPI_Feature::isMacro() const
 {
   return false;
 }
+
+bool ModelAPI_Feature::setDisabled(const bool theFlag)
+{
+  if (myIsDisabled != theFlag) {
+    myIsDisabled = theFlag;
+    if (myIsDisabled)
+      eraseResults();
+    return true;
+  }
+  return false;
+}
+
+bool ModelAPI_Feature::isDisabled() const
+{
+  return myIsDisabled;
+}
index 88f8d72215deae1260ed188492e11af8adc745a9..c2f34865b18080e5fa17ad824a0895396294e4ee 100644 (file)
@@ -26,6 +26,8 @@ class ModelAPI_Feature : public ModelAPI_Object
 {
   ///< list of current results of this feature
   std::list<std::shared_ptr<ModelAPI_Result> > myResults;
+  ///< is feature disabled or not
+  bool myIsDisabled;
  public:
   /// Returns the unique kind of a feature (like "Point")
   virtual const std::string& getKind() = 0;
@@ -106,6 +108,14 @@ class ModelAPI_Feature : public ModelAPI_Object
   /// By default it is empty: it is added to the document this method is called to
   MODELAPI_EXPORT virtual const std::string& documentToAdd();
 
+  /// Enables/disables the feature. The disabled feature has no results and does not participate in
+  /// any calculation.
+  /// \returns true if state is really changed
+  MODELAPI_EXPORT virtual bool setDisabled(const bool theFlag);
+
+  /// Returns the feature is disabled or not.
+  MODELAPI_EXPORT virtual bool isDisabled() const;
+
   /// To virtually destroy the fields of successors
   MODELAPI_EXPORT virtual ~ModelAPI_Feature();