From 61ca3befeb43f693d0b93593268720faca2d121b Mon Sep 17 00:00:00 2001 From: mpv Date: Thu, 15 May 2014 18:05:45 +0400 Subject: [PATCH] Useful methods for sketch operations managements --- src/Model/Model_Data.cpp | 13 ++++++++++ src/Model/Model_Data.h | 4 +++ src/Model/Model_Document.cpp | 25 ++++++++++--------- src/Model/Model_Document.h | 4 +-- src/ModelAPI/ModelAPI_Data.h | 4 +++ src/ModelAPI/ModelAPI_Feature.h | 3 ++- src/SketchPlugin/SketchPlugin_Feature.cpp | 30 +++++++++++++++++++++++ src/SketchPlugin/SketchPlugin_Feature.h | 4 +++ src/SketchPlugin/SketchPlugin_Line.cpp | 1 + src/XGUI/XGUI_Workshop.cpp | 5 ++-- 10 files changed, 76 insertions(+), 17 deletions(-) diff --git a/src/Model/Model_Data.cpp b/src/Model/Model_Data.cpp index 487d0ca91..e6c5c02f2 100644 --- a/src/Model/Model_Data.cpp +++ b/src/Model/Model_Data.cpp @@ -159,3 +159,16 @@ const string& Model_Data::id(const boost::shared_ptr theAttr static string anEmpty; return anEmpty; } + +bool Model_Data::isEqual(const boost::shared_ptr theData) +{ + boost::shared_ptr aData = boost::dynamic_pointer_cast(theData); + if (aData) + return myLab.IsEqual(aData->myLab) == Standard_True; + return false; +} + +bool Model_Data::isValid() +{ + return !myLab.IsNull() && myLab.HasAttribute(); +} diff --git a/src/Model/Model_Data.h b/src/Model/Model_Data.h index 1484f68c8..03ff0c54e 100644 --- a/src/Model/Model_Data.h +++ b/src/Model/Model_Data.h @@ -63,6 +63,10 @@ public: /// Identifier by the id (not fast, iteration by map) /// \param theAttr attribute already created in this data MODEL_EXPORT virtual const std::string& id(const boost::shared_ptr theAttr); + /// Returns true if data belongs to same features + MODEL_EXPORT virtual bool isEqual(const boost::shared_ptr theData); + /// Returns true if it is correctly connected t othe data model + MODEL_EXPORT virtual bool isValid(); /// Initializes object by the attributes: must be called just after the object is created /// for each attribute of the object diff --git a/src/Model/Model_Document.cpp b/src/Model/Model_Document.cpp index 274fc6f1b..73e6adbc7 100644 --- a/src/Model/Model_Document.cpp +++ b/src/Model/Model_Document.cpp @@ -170,7 +170,7 @@ void Model_Document::startOperation() { // check is it nested or not if (myDoc->HasOpenCommand()) { - myIsNested = true; + myNestedStart = myTransactionsAfterSave; } // new command for this myDoc->NewCommand(); @@ -182,10 +182,11 @@ void Model_Document::startOperation() void Model_Document::finishOperation() { + if (myNestedStart > myTransactionsAfterSave) // this nested transaction is owervritten + myNestedStart = 0; // returns false if delta is empty and no transaction was made myIsEmptyTr[myTransactionsAfterSave] = !myDoc->CommitCommand(); myTransactionsAfterSave++; - myIsNested = false; // finish for all subs set::iterator aSubIter = mySubs.begin(); for(; aSubIter != mySubs.end(); aSubIter++) @@ -215,7 +216,7 @@ bool Model_Document::isModified() bool Model_Document::canUndo() { - if (myDoc->GetAvailableUndos() > 0) + if (myDoc->GetAvailableUndos() > 0 && myNestedStart != myTransactionsAfterSave) return true; // check other subs contains operation that can be undoed set::iterator aSubIter = mySubs.begin(); @@ -283,8 +284,8 @@ void Model_Document::addFeature(const boost::shared_ptr theFea aData->setLabel(anObjLab); boost::shared_ptr aThis = Model_Application::getApplication()->getDocument(myID); - theFeature->setData(aData); theFeature->setDoc(aThis); + theFeature->setData(aData); setUniqueName(theFeature); theFeature->initAttributes(); // keep the feature ID to restore document later correctly @@ -398,7 +399,7 @@ Model_Document::Model_Document(const std::string theID) { myDoc->SetUndoLimit(UNDO_LIMIT); myTransactionsAfterSave = 0; - myIsNested = false; + myNestedStart = 0; myDoc->SetNestedTransactionMode(); // to have something in the document and avoid empty doc open/save problem TDataStd_Integer::Set(myDoc->Main().Father(), 0); @@ -509,6 +510,13 @@ void Model_Document::synchronizeFeatures() TCollection_AsciiString(Handle(TDataStd_Comment)::DownCast( aFLabIter.Value())->Get()).ToCString()); + if (aFIter == aFeatures.end()) { // must be before "setData" to redo the sketch line correctly + aFeatures.push_back(aFeature); + aFIter = aFeatures.end(); + } else { + aFIter++; + aFeatures.insert(aFIter, aFeature); + } boost::shared_ptr aData(new Model_Data); TDF_Label aLab = aFLabIter.Value()->Label(); aData->setLabel(aLab); @@ -517,13 +525,6 @@ void Model_Document::synchronizeFeatures() aFeature->setData(aData); aFeature->initAttributes(); - if (aFIter == aFeatures.end()) { - aFeatures.push_back(aFeature); - aFIter = aFeatures.end(); - } else { - aFIter++; - aFeatures.insert(aFIter, aFeature); - } // event: model is updated static Events_ID anEvent = Events_Loop::eventByName(EVENT_FEATURE_CREATED); Model_FeatureUpdatedMessage aMsg(aFeature, anEvent); diff --git a/src/Model/Model_Document.h b/src/Model/Model_Document.h index b314d9dc8..6d5d04b6b 100644 --- a/src/Model/Model_Document.h +++ b/src/Model/Model_Document.h @@ -112,6 +112,8 @@ private: Handle_TDocStd_Document myDoc; ///< OCAF document /// number of transactions after the last "save" call, used for "IsModified" method int myTransactionsAfterSave; + /// number of myTransactionsAfterSave for the nested transaction start + int myNestedStart; /// root labels of the features groups identified by names std::map myGroups; std::vector myGroupsNames; ///< names of added groups to the document @@ -120,8 +122,6 @@ private: std::set mySubs; ///< set of identifiers of sub-documents of this document /// transaction indexes (related to myTransactionsAfterSave) which were empty in this doc std::map myIsEmptyTr; - /// true if the current operation is nested - bool myIsNested; }; #endif diff --git a/src/ModelAPI/ModelAPI_Data.h b/src/ModelAPI/ModelAPI_Data.h index 3b46bc4a0..187654cd8 100644 --- a/src/ModelAPI/ModelAPI_Data.h +++ b/src/ModelAPI/ModelAPI_Data.h @@ -50,6 +50,10 @@ public: /// Identifier by the id (not fast, iteration by map) /// \param theAttr attribute already created in this data virtual const std::string& id(const boost::shared_ptr theAttr) = 0; + /// Returns true if data belongs to same features + virtual bool isEqual(const boost::shared_ptr theData) = 0; + /// Returns true if it is correctly connected t othe data model + virtual bool isValid() = 0; /// Initializes object by the attributes: must be called just after the object is created /// for each attribute of the object diff --git a/src/ModelAPI/ModelAPI_Feature.h b/src/ModelAPI/ModelAPI_Feature.h index b55e79846..1dd7b12db 100644 --- a/src/ModelAPI/ModelAPI_Feature.h +++ b/src/ModelAPI/ModelAPI_Feature.h @@ -62,7 +62,8 @@ protected: {} /// Sets the data manager of an object (document does) - MODELAPI_EXPORT void setData(boost::shared_ptr theData) {myData = theData;} + MODELAPI_EXPORT virtual void setData(boost::shared_ptr theData) + {myData = theData;} /// Sets the data manager of an object (document does) MODELAPI_EXPORT void setDoc(boost::shared_ptr theDoc) {myDoc = theDoc;} diff --git a/src/SketchPlugin/SketchPlugin_Feature.cpp b/src/SketchPlugin/SketchPlugin_Feature.cpp index e7d9d292a..00c849fc9 100644 --- a/src/SketchPlugin/SketchPlugin_Feature.cpp +++ b/src/SketchPlugin/SketchPlugin_Feature.cpp @@ -1,4 +1,34 @@ #include "SketchPlugin_Feature.h" +#include "SketchPlugin_Sketch.h" +#include +#include +#include + +SketchPlugin_Feature::SketchPlugin_Feature() +{ + mySketch = 0; +} + +void SketchPlugin_Feature::setData(boost::shared_ptr theData) +{ + ModelAPI_Feature::setData(theData); + + // find sketch that references to this feature + int aSketches = document()->size("Construction"); + for(int a = 0; a < aSketches && !mySketch; a++) { + boost::shared_ptr aSketch = + boost::dynamic_pointer_cast(document()->feature("Construction", a)); + std::list > aList = + aSketch->data()->reflist(SKETCH_ATTR_FEATURES)->list(); + std::list >::iterator aSub = aList.begin(); + for(; aSub != aList.end(); aSub++) { + if ((*aSub)->data()->isEqual(theData)) { + mySketch = aSketch.get(); + break; + } + } + } +} void SketchPlugin_Feature::setPreview(const boost::shared_ptr& theShape) { diff --git a/src/SketchPlugin/SketchPlugin_Feature.h b/src/SketchPlugin/SketchPlugin_Feature.h index d02728011..d83e21cce 100644 --- a/src/SketchPlugin/SketchPlugin_Feature.h +++ b/src/SketchPlugin/SketchPlugin_Feature.h @@ -43,6 +43,10 @@ protected: void setSketch(SketchPlugin_Sketch* theSketch) {mySketch = theSketch;} /// Returns the sketch of this feature SketchPlugin_Sketch* sketch() {return mySketch;} + /// initializes mySketch + SketchPlugin_Feature(); + /// Sets the data manager of an object and here initializes mySketch field + SKETCHPLUGIN_EXPORT virtual void setData(boost::shared_ptr theData); friend class SketchPlugin_Sketch; diff --git a/src/SketchPlugin/SketchPlugin_Line.cpp b/src/SketchPlugin/SketchPlugin_Line.cpp index 5c71d3779..ee3f8c861 100644 --- a/src/SketchPlugin/SketchPlugin_Line.cpp +++ b/src/SketchPlugin/SketchPlugin_Line.cpp @@ -15,6 +15,7 @@ using namespace std; const double PLANE_SIZE = 200; SketchPlugin_Line::SketchPlugin_Line() + : SketchPlugin_Feature() { setSketch(0); } diff --git a/src/XGUI/XGUI_Workshop.cpp b/src/XGUI/XGUI_Workshop.cpp index aa2318703..2f5b848a3 100644 --- a/src/XGUI/XGUI_Workshop.cpp +++ b/src/XGUI/XGUI_Workshop.cpp @@ -470,8 +470,9 @@ void XGUI_Workshop::onUndo() objectBrowser()->setCurrentIndex(QModelIndex()); boost::shared_ptr aMgr = ModelAPI_PluginManager::get(); boost::shared_ptr aDoc = aMgr->rootDocument(); - if (!operationMgr()->abortOperation()) - return; + //if (!operationMgr()->abortOperation()) + // return; + operationMgr()->abortOperation(); aDoc->undo(); updateCommandStatus(); } -- 2.39.2