0029142: Exception on Redo.
authorszy <szy@opencascade.com>
Mon, 20 Nov 2017 14:31:15 +0000 (17:31 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 23 Nov 2017 10:05:30 +0000 (13:05 +0300)
Order of attributes deltas is fixed.

src/TDF/TDF_Data.cxx
src/TDF/TDF_Data.hxx
src/TDF/TDF_Delta.hxx
src/TDF/TDF_Delta.lxx
tests/bugs/caf/bug29142 [new file with mode: 0644]

index a6e8f12..96cdd85 100644 (file)
@@ -18,6 +18,8 @@
 #include <Standard_NoMoreObject.hxx>
 #include <Standard_NullObject.hxx>
 #include <Standard_Type.hxx>
 #include <Standard_NoMoreObject.hxx>
 #include <Standard_NullObject.hxx>
 #include <Standard_Type.hxx>
+#include <Standard_GUID.hxx>
+#include <NCollection_Array1.hxx>
 #include <TCollection_AsciiString.hxx>
 #include <TDF_Attribute.hxx>
 #include <TDF_AttributeDelta.hxx>
 #include <TCollection_AsciiString.hxx>
 #include <TDF_Attribute.hxx>
 #include <TDF_AttributeDelta.hxx>
@@ -37,6 +39,8 @@
 #include <TDF_Tool.hxx>
 #include <TDF_Transaction.hxx>
 
 #include <TDF_Tool.hxx>
 #include <TDF_Transaction.hxx>
 
+typedef NCollection_Array1<Handle(TDF_AttributeDelta)> TDF_Array1OfAttributeIDelta;
+
 IMPLEMENT_STANDARD_RTTIEXT(TDF_Data,Standard_Transient)
 
 #undef DEB_DELTA_CREATION
 IMPLEMENT_STANDARD_RTTIEXT(TDF_Data,Standard_Transient)
 
 #undef DEB_DELTA_CREATION
@@ -365,15 +369,56 @@ Standard_Boolean TDF_Data::IsApplicable
   return !aDelta.IsNull() && aDelta->IsApplicable(myTime);
 }
 
   return !aDelta.IsNull() && aDelta->IsApplicable(myTime);
 }
 
-
+//=======================================================================
+//function : FixOrder
+//purpose  : 
+//=======================================================================
+void TDF_Data::FixOrder(const Handle(TDF_Delta)& theDelta)
+{
+  const TDF_AttributeDeltaList& attList = theDelta->AttributeDeltas();
+  Handle(TDF_AttributeDelta) attDelta;
+  Handle(TDF_Attribute) att;
+  Standard_Integer i, indx1(0), indx2(0);
+  Standard_GUID aGuid;
+  TDF_ListIteratorOfAttributeDeltaList itr(attList) ;
+  for (i=1; itr.More(); itr.Next(), i++) {
+    attDelta = itr.Value();
+    if(indx1) {
+      att = attDelta->Attribute();
+      if((att->ID() == aGuid) && (attDelta->IsKind(STANDARD_TYPE(TDF_DeltaOnAddition)))) {
+        indx2 = i;
+        break;
+      }
+    } else 
+      if (attDelta->IsKind(STANDARD_TYPE(TDF_DeltaOnRemoval))) {
+        att = attDelta->Attribute();
+        aGuid = att->ID();
+        indx1 = i;
+      }        
+  }
+  if(indx1 && indx2) {
+    TDF_Array1OfAttributeIDelta anArray(1, attList.Extent());
+    itr.Initialize(attList);
+    for (i=1; itr.More(); itr.Next(), i++) 
+      anArray.SetValue(i, itr.Value());
+    Handle(TDF_AttributeDelta) attDelta1, attDelta2;
+    attDelta1 = anArray.Value(indx1);
+    attDelta2 = anArray.Value(indx2);
+    anArray.SetValue(indx1, attDelta2);
+    anArray.SetValue(indx2, attDelta1);
+    TDF_AttributeDeltaList attList2;
+    for(i=1; i<= anArray.Upper(); i++)
+      attList2.Append(anArray.Value(i));
+    theDelta->ReplaceDeltaList(attList2);
+  }
+}
 //=======================================================================
 //function : Undo
 //purpose  : Applies a delta to undo  actions.
 //=======================================================================
 
 //=======================================================================
 //function : Undo
 //purpose  : Applies a delta to undo  actions.
 //=======================================================================
 
-Handle(TDF_Delta) TDF_Data::Undo
-(const Handle(TDF_Delta)& aDelta,
- const Standard_Boolean withDelta)
+Handle(TDF_Delta) TDF_Data::Undo(const Handle(TDF_Delta)& aDelta,
+                                 const Standard_Boolean withDelta)
 {
   Handle(TDF_Delta) newDelta;
   if (!aDelta.IsNull ()) {
 {
   Handle(TDF_Delta) newDelta;
   if (!aDelta.IsNull ()) {
@@ -385,6 +430,7 @@ Handle(TDF_Delta) TDF_Data::Undo
 #endif
       aDelta->BeforeOrAfterApply(Standard_True);
       myNotUndoMode = Standard_False;
 #endif
       aDelta->BeforeOrAfterApply(Standard_True);
       myNotUndoMode = Standard_False;
+      FixOrder(aDelta);
       aDelta->Apply ();
       myNotUndoMode = Standard_True;
       if (withDelta) {
       aDelta->Apply ();
       myNotUndoMode = Standard_True;
       if (withDelta) {
index cab918f..5856a32 100644 (file)
@@ -88,7 +88,7 @@ public:
     Standard_Boolean NotUndoMode() const;
   
   //! Dumps the Data on <aStream>.
     Standard_Boolean NotUndoMode() const;
   
   //! Dumps the Data on <aStream>.
-  Standard_EXPORT Standard_OStream& Dump (Standard_OStream& anOS) const;
+    Standard_EXPORT Standard_OStream& Dump (Standard_OStream& anOS) const;
 Standard_OStream& operator<< (Standard_OStream& anOS) const
 {
   return Dump(anOS);
 Standard_OStream& operator<< (Standard_OStream& anOS) const
 {
   return Dump(anOS);
@@ -147,6 +147,8 @@ protected:
 
 private:
 
 
 private:
 
+  //! Fixes order of Attributes' Deltas
+  void FixOrder(const Handle(TDF_Delta)& theDelta);
   
   //! Increments the transaction number and returns it.
   Standard_EXPORT Standard_Integer OpenTransaction();
   
   //! Increments the transaction number and returns it.
   Standard_EXPORT Standard_Integer OpenTransaction();
index 9e64d14..a1c759d 100644 (file)
@@ -74,7 +74,7 @@ public:
   
   //! Associates a name <theName> with this delta
     void SetName (const TCollection_ExtendedString& theName);
   
   //! Associates a name <theName> with this delta
     void SetName (const TCollection_ExtendedString& theName);
-  
+
   Standard_EXPORT void Dump (Standard_OStream& OS) const;
 
 
   Standard_EXPORT void Dump (Standard_OStream& OS) const;
 
 
@@ -95,11 +95,11 @@ protected:
   //! TDF_Data.
   Standard_EXPORT void AddAttributeDelta (const Handle(TDF_AttributeDelta)& anAttributeDelta);
 
   //! TDF_Data.
   Standard_EXPORT void AddAttributeDelta (const Handle(TDF_AttributeDelta)& anAttributeDelta);
 
-
-
 private:
 
 private:
 
-  
+  //! Replaces Attribute Delta List
+  Standard_EXPORT void ReplaceDeltaList(const TDF_AttributeDeltaList& theList);
+
   Standard_EXPORT void BeforeOrAfterApply (const Standard_Boolean before) const;
   
   Standard_EXPORT void Apply();
   Standard_EXPORT void BeforeOrAfterApply (const Standard_Boolean before) const;
   
   Standard_EXPORT void Apply();
index 074714f..3b6bd6a 100644 (file)
@@ -41,3 +41,6 @@ inline void TDF_Delta::SetName (const TCollection_ExtendedString& theName)
 
 inline TCollection_ExtendedString TDF_Delta::Name () const
 { return myName; }
 
 inline TCollection_ExtendedString TDF_Delta::Name () const
 { return myName; }
+
+inline void TDF_Delta::ReplaceDeltaList(const TDF_AttributeDeltaList& theList)
+{ myAttDeltaList = theList;}
\ No newline at end of file
diff --git a/tests/bugs/caf/bug29142 b/tests/bugs/caf/bug29142
new file mode 100644 (file)
index 0000000..63cf323
--- /dev/null
@@ -0,0 +1,51 @@
+puts "================"
+puts "bug0029142"
+puts "================"
+puts ""
+
+######################################################
+# Checks bug of Undo mechanism
+######################################################
+NewDocument D BinOcaf
+UndoLimit D 100
+set Lab1 [Label D 0:1:1]
+
+#1. Set Integer attribute
+NewCommand D
+SetInteger  D $Lab1 111
+
+#2. Set Real attribute
+NewCommand D
+SetReal D $Lab1 0.234
+
+#3. Forget Integer attribute
+NewCommand D
+ForgetAtt D $Lab1 2a96b606-ec8b-11d0-bee7-080009dc3333
+
+#4. Set new Integer attribute
+SetInteger D $Lab1 222
+#5. Undo
+NewCommand D
+set IsGoodUndo 1
+if [catch {Undo D}] {
+   puts "Error during Document Undo"
+   set IsGoodUndo 0
+}
+
+#6. Redo
+set IsGoodRedo 1
+if [catch {Redo D}] {
+   puts "Error during Document Redo"
+   set IsGoodRedo 0
+}
+
+
+#7. Check result
+if {$IsGoodUndo == 1 & $IsGoodRedo == 1} {
+    puts "bug0029142: OK"
+} else {
+    puts "bug0029142: ERROR"
+}
+
+#8. Close document
+Close D
\ No newline at end of file