Salome HOME
Issue #1112 tab key doesn't work on the last field of left panels
[modules/shaper.git] / src / Model / Model_Document.cpp
old mode 100644 (file)
new mode 100755 (executable)
index ecd12cf..ec071b4
 #include <TDataStd_Comment.hxx>
 #include <TDF_ChildIDIterator.hxx>
 #include <TDataStd_ReferenceArray.hxx>
+#include <TDataStd_ReferenceList.hxx>
 #include <TDataStd_IntegerArray.hxx>
 #include <TDataStd_HLabelArray1.hxx>
 #include <TDataStd_Name.hxx>
+#include <TDataStd_AsciiString.hxx>
 #include <TDF_Reference.hxx>
 #include <TDF_ChildIDIterator.hxx>
 #include <TDF_LabelMapHasher.hxx>
@@ -293,6 +295,10 @@ void Model_Document::close(const bool theForever)
     mySelectionFeature.reset();
   } else {
     setCurrentFeature(FeaturePtr(), false); // disables all features
+    // update the OB: features are disabled (on remove of Part)
+    Events_Loop* aLoop = Events_Loop::loop();
+    static Events_ID aDeleteEvent = Events_Loop::eventByName(EVENT_OBJECT_DELETED);
+    aLoop->flush(aDeleteEvent);
   }
 
   std::static_pointer_cast<Model_Session>(Model_Session::get())->setCheckTransactions(true);
@@ -360,7 +366,7 @@ static bool isEqualContent(Handle(TDF_Attribute) theAttr1, Handle(TDF_Attribute)
       return false;
     if (anArr1->Lower() == anArr2->Lower() && anArr1->Upper() == anArr2->Upper()) {
       for(int a = anArr1->Lower(); a <= anArr1->Upper(); a++)
-        if (anArr1->Value(a) != anArr2->Value(a))
+        if (a != 1 && anArr1->Value(a) != anArr2->Value(a)) // second is for display
           return false;
       return true;
     }
@@ -382,6 +388,42 @@ static bool isEqualContent(Handle(TDF_Attribute) theAttr1, Handle(TDF_Attribute)
         }
       return true;
     }
+  } else if (Standard_GUID::IsEqual(theAttr1->ID(), TDataStd_ReferenceArray::GetID())) {
+    Handle(TDataStd_ReferenceArray) anArr1 = Handle(TDataStd_ReferenceArray)::DownCast(theAttr1);
+    Handle(TDataStd_ReferenceArray) anArr2 = Handle(TDataStd_ReferenceArray)::DownCast(theAttr2);
+    if (anArr1.IsNull() && anArr2.IsNull())
+      return true;
+    if (anArr1.IsNull() || anArr2.IsNull())
+      return false;
+    if (anArr1->Lower() == anArr2->Lower() && anArr1->Upper() == anArr2->Upper()) {
+      for(int a = anArr1->Lower(); a <= anArr1->Upper(); a++)
+        if (anArr1->Value(a) != anArr2->Value(a)) {
+          // avoid the transaction ID checking
+          if (a == 2 && anArr1->Upper() == 2 && anArr2->Label().Tag() == 1 &&
+            (anArr2->Label().Depth() == 4 || anArr2->Label().Depth() == 6))
+            continue;
+          return false;
+        }
+      return true;
+    }
+  } else if (Standard_GUID::IsEqual(theAttr1->ID(), TDataStd_ReferenceList::GetID())) {
+    Handle(TDataStd_ReferenceList) aList1 = Handle(TDataStd_ReferenceList)::DownCast(theAttr1);
+    Handle(TDataStd_ReferenceList) aList2= Handle(TDataStd_ReferenceList)::DownCast(theAttr2);
+    if (aList1.IsNull() && aList2.IsNull())
+      return true;
+    if (aList1.IsNull() || aList2.IsNull())
+      return false;
+    const TDF_LabelList& aLList1 = aList1->List();
+    const TDF_LabelList& aLList2 = aList2->List();
+    TDF_ListIteratorOfLabelList aLIter1(aLList1);
+    TDF_ListIteratorOfLabelList aLIter2(aLList2);
+    for(; aLIter1.More() && aLIter2.More(); aLIter1.Next(), aLIter2.Next()) {
+      if (aLIter1.Value() != aLIter2.Value())
+        return false;
+    }
+    return !aLIter1.More() && !aLIter2.More(); // both lists are with the same size
+  } else if (Standard_GUID::IsEqual(theAttr1->ID(), TDF_TagSource::GetID())) {
+    return true; // it just for created and removed feature: nothing is changed
   }
   return false;
 }
@@ -400,11 +442,16 @@ static bool isEmptyTransaction(const Handle(TDocStd_Document)& theDoc) {
   const TDF_AttributeDeltaList& anAttrs = aDelta->AttributeDeltas();
   for (TDF_ListIteratorOfAttributeDeltaList anAttr(anAttrs); anAttr.More(); anAttr.Next()) {
     Handle(TDF_AttributeDelta)& anADelta = anAttr.Value();
-    if (!anADelta->Label().IsNull() && !anADelta->Attribute().IsNull()) {
-      Handle(TDF_Attribute) aCurrentAttr;
-      if (anADelta->Label().FindAttribute(anADelta->Attribute()->ID(), aCurrentAttr)) {
-        if (isEqualContent(anADelta->Attribute(), aCurrentAttr)) {
-          continue; // attribute is not changed actually
+    Handle(TDF_DeltaOnAddition) anAddition = Handle(TDF_DeltaOnAddition)::DownCast(anADelta);
+    if (anAddition.IsNull()) { // if the attribute was added, transaction is not empty
+      if (!anADelta->Label().IsNull() && !anADelta->Attribute().IsNull()) {
+        Handle(TDF_Attribute) aCurrentAttr;
+        if (anADelta->Label().FindAttribute(anADelta->Attribute()->ID(), aCurrentAttr)) {
+          if (isEqualContent(anADelta->Attribute(), aCurrentAttr)) {
+            continue; // attribute is not changed actually
+          }
+        } else if (Standard_GUID::IsEqual(anADelta->Attribute()->ID(), TDataStd_AsciiString::GetID())) {
+          continue; // error message is disappeared
         }
       }
     }
@@ -534,9 +581,9 @@ void Model_Document::abortOperation()
     if (!myNestedNum.empty())
       (*myNestedNum.rbegin())--;
     // roll back the needed number of transactions
-    // make commit/undo to get the modification delta
     //myDoc->AbortCommand();
-    if (myDoc->CommitCommand()) {
+    // instead of abort, do commit and undo: to get the delta of modifications
+    if (myDoc->CommitCommand())  {
       modifiedLabels(myDoc, aDeltaLabels);
       myDoc->Undo();
     }
@@ -591,6 +638,8 @@ bool Model_Document::canUndo()
 
 void Model_Document::undoInternal(const bool theWithSubs, const bool theSynchronize)
 {
+  if (myTransactions.empty())
+    return;
   int aNumTransactions = myTransactions.rbegin()->myOCAFNum;
   myRedos.push_back(*myTransactions.rbegin());
   myTransactions.pop_back();
@@ -821,6 +870,8 @@ const int Model_Document::index(std::shared_ptr<ModelAPI_Object> theObject)
 
 int Model_Document::size(const std::string& theGroupID)
 {
+  if (myObjs == 0) // may be on close
+    return 0;
   return myObjs->size(theGroupID);
 }