From a4668a870ad842fffc069c9fbb1afcd55ece5cf3 Mon Sep 17 00:00:00 2001 From: mpv Date: Fri, 8 May 2015 12:01:58 +0300 Subject: [PATCH] Initial implementation of working with history: issue #499 --- src/Model/Model_Document.cpp | 61 +++++++++++++++++++++++++++++++ src/Model/Model_Document.h | 11 ++++++ src/ModelAPI/ModelAPI_Document.h | 9 +++++ src/ModelAPI/ModelAPI_Feature.cpp | 16 ++++++++ src/ModelAPI/ModelAPI_Feature.h | 10 +++++ 5 files changed, 107 insertions(+) diff --git a/src/Model/Model_Document.cpp b/src/Model/Model_Document.cpp index 0535ef7f2..7ddc7dcfd 100644 --- a/src/Model/Model_Document.cpp +++ b/src/Model/Model_Document.cpp @@ -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( + 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 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(); // null feature means the higher than first +} + +void Model_Document::setCurrentFeature(std::shared_ptr theCurrent) +{ + static TDF_Label aRefLab = generalLabel().FindChild(TAG_CURRENT_FEATURE); + if (theCurrent.get()) { + std::shared_ptr aData = std::static_pointer_cast(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(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()) diff --git a/src/Model/Model_Document.h b/src/Model/Model_Document.h index a307e7796..17c14caa9 100644 --- a/src/Model/Model_Document.h +++ b/src/Model/Model_Document.h @@ -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 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 theCurrent); + /// Creates a construction cresults MODEL_EXPORT virtual std::shared_ptr createConstruction( const std::shared_ptr& 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 diff --git a/src/ModelAPI/ModelAPI_Document.h b/src/ModelAPI/ModelAPI_Document.h index 9fe19db66..dc43fac41 100644 --- a/src/ModelAPI/ModelAPI_Document.h +++ b/src/ModelAPI/ModelAPI_Document.h @@ -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 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 theCurrent) = 0; + /// To virtually destroy the fields of successors MODELAPI_EXPORT virtual ~ModelAPI_Document(); diff --git a/src/ModelAPI/ModelAPI_Feature.cpp b/src/ModelAPI/ModelAPI_Feature.cpp index 8a5d93cbd..1a756e2d8 100644 --- a/src/ModelAPI/ModelAPI_Feature.cpp +++ b/src/ModelAPI/ModelAPI_Feature.cpp @@ -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; +} diff --git a/src/ModelAPI/ModelAPI_Feature.h b/src/ModelAPI/ModelAPI_Feature.h index 88f8d7221..c2f34865b 100644 --- a/src/ModelAPI/ModelAPI_Feature.h +++ b/src/ModelAPI/ModelAPI_Feature.h @@ -26,6 +26,8 @@ class ModelAPI_Feature : public ModelAPI_Object { ///< list of current results of this feature std::list > 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(); -- 2.39.2