#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 <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
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.
//=======================================================================
-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 ()) {
#endif
aDelta->BeforeOrAfterApply(Standard_True);
myNotUndoMode = Standard_False;
+ FixOrder(aDelta);
aDelta->Apply ();
myNotUndoMode = Standard_True;
if (withDelta) {
--- /dev/null
+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