1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-10 18:51:21 +03:00

0029142: Exception on Redo.

Order of attributes deltas is fixed.
This commit is contained in:
szy 2017-11-20 17:31:15 +03:00 committed by bugmaster
parent 0ccd71060a
commit a7378539f1
5 changed files with 111 additions and 9 deletions

View File

@ -18,6 +18,8 @@
#include <Standard_NoMoreObject.hxx> #include <Standard_NoMoreObject.hxx>
#include <Standard_NullObject.hxx> #include <Standard_NullObject.hxx>
#include <Standard_Type.hxx> #include <Standard_Type.hxx>
#include <Standard_GUID.hxx>
#include <NCollection_Array1.hxx>
#include <TCollection_AsciiString.hxx> #include <TCollection_AsciiString.hxx>
#include <TDF_Attribute.hxx> #include <TDF_Attribute.hxx>
#include <TDF_AttributeDelta.hxx> #include <TDF_AttributeDelta.hxx>
@ -37,6 +39,8 @@
#include <TDF_Tool.hxx> #include <TDF_Tool.hxx>
#include <TDF_Transaction.hxx> #include <TDF_Transaction.hxx>
typedef NCollection_Array1<Handle(TDF_AttributeDelta)> TDF_Array1OfAttributeIDelta;
IMPLEMENT_STANDARD_RTTIEXT(TDF_Data,Standard_Transient) IMPLEMENT_STANDARD_RTTIEXT(TDF_Data,Standard_Transient)
#undef DEB_DELTA_CREATION #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 //function : Undo
//purpose : Applies a delta to undo actions. //purpose : Applies a delta to undo actions.
//======================================================================= //=======================================================================
Handle(TDF_Delta) TDF_Data::Undo Handle(TDF_Delta) TDF_Data::Undo(const Handle(TDF_Delta)& aDelta,
(const Handle(TDF_Delta)& aDelta, const Standard_Boolean withDelta)
const Standard_Boolean withDelta)
{ {
Handle(TDF_Delta) newDelta; Handle(TDF_Delta) newDelta;
if (!aDelta.IsNull ()) { if (!aDelta.IsNull ()) {
@ -385,6 +430,7 @@ Handle(TDF_Delta) TDF_Data::Undo
#endif #endif
aDelta->BeforeOrAfterApply(Standard_True); aDelta->BeforeOrAfterApply(Standard_True);
myNotUndoMode = Standard_False; myNotUndoMode = Standard_False;
FixOrder(aDelta);
aDelta->Apply (); aDelta->Apply ();
myNotUndoMode = Standard_True; myNotUndoMode = Standard_True;
if (withDelta) { if (withDelta) {

View File

@ -88,7 +88,7 @@ public:
Standard_Boolean NotUndoMode() const; Standard_Boolean NotUndoMode() const;
//! Dumps the Data on <aStream>. //! 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 Standard_OStream& operator<< (Standard_OStream& anOS) const
{ {
return Dump(anOS); 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. //! Increments the transaction number and returns it.
Standard_EXPORT Standard_Integer OpenTransaction(); Standard_EXPORT Standard_Integer OpenTransaction();

View File

@ -95,10 +95,10 @@ protected:
//! TDF_Data. //! TDF_Data.
Standard_EXPORT void AddAttributeDelta (const Handle(TDF_AttributeDelta)& anAttributeDelta); 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 BeforeOrAfterApply (const Standard_Boolean before) const;

View File

@ -41,3 +41,6 @@ inline void TDF_Delta::SetName (const TCollection_ExtendedString& theName)
inline TCollection_ExtendedString TDF_Delta::Name () const inline TCollection_ExtendedString TDF_Delta::Name () const
{ return myName; } { return myName; }
inline void TDF_Delta::ReplaceDeltaList(const TDF_AttributeDeltaList& theList)
{ myAttDeltaList = theList;}

51
tests/bugs/caf/bug29142 Normal file
View File

@ -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