0033661: Data Exchange, Step Import - Tessellated GDTs are not imported
[occt.git] / src / TDocStd / TDocStd_Document.cxx
1 // Copyright (c) 2006-2014 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14 #include <TDocStd_Document.hxx>
15
16 #include <CDM_Document.hxx>
17 #include <CDM_MetaData.hxx>
18 #include <Standard_Dump.hxx>
19 #include <Standard_Type.hxx>
20 #include <TCollection_AsciiString.hxx>
21 #include <TCollection_ExtendedString.hxx>
22 #include <TDF_AttributeDelta.hxx>
23 #include <TDF_AttributeDeltaList.hxx>
24 #include <TDF_AttributeIterator.hxx>
25 #include <TDF_Data.hxx>
26 #include <TDF_Delta.hxx>
27 #include <TDF_Label.hxx>
28 #include <TDF_ListIteratorOfAttributeList.hxx>
29 #include <TDF_ListIteratorOfDeltaList.hxx>
30 #include <TDF_Reference.hxx>
31 #include <TDocStd.hxx>
32 #include <TDocStd_Application.hxx>
33 #include <TDocStd_CompoundDelta.hxx>
34 #include <TDocStd_Context.hxx>
35 #include <TDocStd_LabelIDMapDataMap.hxx>
36 #include <TDocStd_Modified.hxx>
37 #include <TDocStd_Owner.hxx>
38 #include <TDocStd_XLink.hxx>
39 #include <TDocStd_XLinkIterator.hxx>
40
41 IMPLEMENT_STANDARD_RTTIEXT(TDocStd_Document,CDM_Document)
42
43 // List should have a RemoveLast...
44 #define TDocStd_List_RemoveLast(theList) \
45 TDF_ListIteratorOfDeltaList it(theList); \
46 Standard_Integer i,n = theList.Extent(); \
47 for (i = 1; i < n; i++) it.Next(); \
48 theList.Remove(it);
49
50 #undef DEB_TRANS
51
52 #undef DEB_DELTA
53
54 #define SRN_DELTA_COMPACT
55
56 //=======================================================================
57 //function : Get
58 //purpose  : 
59 //=======================================================================
60
61 Handle(TDocStd_Document) TDocStd_Document::Get (const TDF_Label& acces)
62 {
63   // avoid creation of Handle(TDF_Data) during TDF_Data destruction
64   if (acces.Root().HasAttribute()) {
65     return TDocStd_Owner::GetDocument(acces.Data());
66   }
67   return Handle(TDocStd_Document)();
68 }
69
70 //=======================================================================
71 //function : TDocStd_Document
72 //purpose  : 
73 //=======================================================================
74
75
76 TDocStd_Document::TDocStd_Document(const TCollection_ExtendedString& aStorageFormat) :
77 myStorageFormat(aStorageFormat),
78 myData (new TDF_Data()),
79 myUndoLimit(0),
80 myUndoTransaction ("UNDO"),
81 mySaveTime(0),
82 myIsNestedTransactionMode(0),
83 mySaveEmptyLabels(Standard_False),
84 myStorageFormatVersion(TDocStd_FormatVersion_CURRENT)
85 {
86   myUndoTransaction.Initialize (myData);
87   TDocStd_Owner::SetDocument(myData,this);
88
89 #ifdef SRN_DELTA_COMPACT
90   myFromUndo.Nullify();
91   myFromRedo.Nullify();
92 #endif
93 }
94
95
96 //=======================================================================
97 //function : IsSaved
98 //purpose  : 
99 //=======================================================================
100
101 Standard_Boolean TDocStd_Document::IsSaved() const
102 {
103   return CDM_Document::IsStored();
104 }
105
106
107 //=======================================================================
108 //function : GetName
109 //purpose  : 
110 //=======================================================================
111
112 TCollection_ExtendedString TDocStd_Document::GetName () const
113 {
114   return CDM_Document::MetaData()->Name();
115 }
116
117 //=======================================================================
118 //function : GetPath
119 //purpose  : 
120 //=======================================================================
121
122 TCollection_ExtendedString TDocStd_Document::GetPath () const
123 {
124   return CDM_Document::MetaData()->Path();
125 }
126
127
128 //=======================================================================
129 //function : SetData
130 //purpose  : 
131 //=======================================================================
132
133 void TDocStd_Document::SetData (const Handle(TDF_Data)& D)
134 {
135   myData = D;
136   myUndoTransaction.Initialize (myData);
137 }
138
139 //=======================================================================
140 //function : GetData
141 //purpose  : 
142 //=======================================================================
143
144 Handle(TDF_Data) TDocStd_Document::GetData () const
145 {
146   return myData;
147 }
148
149 //=======================================================================
150 //function : Main
151 //purpose  : 
152 //=======================================================================
153
154 TDF_Label TDocStd_Document::Main () const
155
156   return  myData->Root().FindChild(1,Standard_True);
157 }
158
159 //=======================================================================
160 //function : IsEmpty
161 //purpose  : 
162 //=======================================================================
163
164 Standard_Boolean TDocStd_Document::IsEmpty() const
165 {
166   TDF_AttributeIterator It (Main());
167   return !It.More();
168 }
169
170 //=======================================================================
171 //function : IsValid
172 //purpose  : 
173 //=======================================================================
174
175 Standard_Boolean TDocStd_Document::IsValid() const
176 {
177   return TDocStd_Modified::IsEmpty(Main());
178 }
179
180 //=======================================================================
181 //function : SetModified
182 //purpose  : 
183 //=======================================================================
184
185 void TDocStd_Document::SetModified (const TDF_Label& L)                                  
186 {  
187   TDocStd_Modified::Add(L);
188 }
189
190 //=======================================================================
191 //function : IsModified
192 //purpose  : 
193 //=======================================================================
194 //Standard_Boolean TDocStd_Document::IsModified (const TDF_Label& L) const                                 
195 //{  
196 //  return TDocStd_Modified::Contains(L);
197 //}
198
199 //=======================================================================
200 //function : PurgeModified
201 //purpose  : 
202 //=======================================================================
203
204 void TDocStd_Document::PurgeModified()
205 {   
206   TDocStd_Modified::Clear(Main()); 
207 }
208
209 //=======================================================================
210 //function : GetModified
211 //purpose  : 
212 //=======================================================================
213
214 const TDF_LabelMap&  TDocStd_Document::GetModified() const
215 {  
216   return TDocStd_Modified::Get(Main());  
217 }
218
219
220
221 //=======================================================================
222 //function : Update
223 //purpose  : 
224 //=======================================================================
225
226 void TDocStd_Document::Update(const Handle(CDM_Document)& /*aToDocument*/,
227                                const Standard_Integer aReferenceIdentifier,
228                                const Standard_Address aModifContext) 
229 {
230   const TDocStd_Context* CC = static_cast<TDocStd_Context*> (aModifContext);
231   if (CC->ModifiedReferences() || !IsUpToDate(aReferenceIdentifier)) {
232     TCollection_AsciiString aDocEntry(aReferenceIdentifier);
233     UpdateReferences(aDocEntry);
234     SetIsUpToDate(aReferenceIdentifier);
235   }
236 }
237
238 //=======================================================================
239 //function : NewCommand
240 //purpose  : 
241 //=======================================================================
242
243 void TDocStd_Document::NewCommand()
244 {
245 #ifdef OCCT_DEBUG_TRANS
246   if (myUndoTransaction.IsOpen() && myData->Transaction() > 1) {
247     throw Standard_DomainError("NewCommand : many open transactions");
248   }
249 #endif
250
251   CommitTransaction();
252   OpenTransaction();
253
254 #ifdef OCCT_DEBUG_TRANS
255   std::cout<<"End NewCommand"<<std::endl;
256 #endif
257 }
258
259
260 //=======================================================================
261 //function : HasOpenCommand
262 //purpose  : 
263 //=======================================================================
264 Standard_Boolean TDocStd_Document::HasOpenCommand() const
265 {
266   return myUndoTransaction.IsOpen();
267 }
268
269 //=======================================================================
270 //function : OpenCommand
271 //purpose  : 
272 //=======================================================================
273
274 void TDocStd_Document::OpenCommand ()
275 {
276   if (!myIsNestedTransactionMode && myUndoTransaction.IsOpen()) {
277     throw Standard_DomainError("TDocStd_Document::OpenCommand : already open");
278   }
279   OpenTransaction();
280 //  if (myUndoLimit != 0) myUndoTransaction.Open();
281 }
282
283 //=======================================================================
284 //function : CommitCommand
285 //purpose  : 
286 //=======================================================================
287
288 Standard_Boolean TDocStd_Document::CommitCommand ()
289 {
290   return CommitTransaction();
291 }
292
293
294 //=======================================================================
295 //function : AbortCommand
296 //purpose  : 
297 //=======================================================================
298
299 void TDocStd_Document::AbortCommand ()
300
301   AbortTransaction();
302 }
303
304
305 //=======================================================================
306 //function : CommitTransaction
307 //purpose  : Private method.
308 //=======================================================================
309
310 Standard_Boolean TDocStd_Document::CommitTransaction()
311 {
312   myData->AllowModification(Standard_True);
313
314   Standard_Boolean isDone = Standard_False;
315   // nested transaction mode
316   if (myIsNestedTransactionMode && myUndoTransaction.IsOpen()) {
317
318     Handle(TDF_Delta) D = myUndoTransaction.Commit(Standard_True);
319     Handle(TDocStd_CompoundDelta) aCompDelta =
320       Handle(TDocStd_CompoundDelta)::DownCast(myUndoFILO.First());
321     AppendDeltaToTheFirst(aCompDelta, D);
322     D = aCompDelta;
323     myUndoFILO.RemoveFirst();
324     if(myUndoFILO.Extent()) {
325       aCompDelta = Handle(TDocStd_CompoundDelta)::DownCast(myUndoFILO.First());
326       AppendDeltaToTheFirst(aCompDelta, D);
327       myUndoTransaction.Open();
328     }
329     else {
330       if(!D->IsEmpty()) {
331         myUndos.Append(D);
332         myRedos.Clear(); // if we push an Undo we clear the redos
333         isDone = Standard_True;
334       }
335     }
336
337     // deny modifications if the transaction is not opened
338     if(myOnlyTransactionModification) {
339       myData->AllowModification(myUndoTransaction.IsOpen() && myUndoLimit
340                                 ? Standard_True :Standard_False);
341     }
342
343   } else {
344
345   // are we undoing...
346     if (myUndoLimit != 0 && myUndoTransaction.IsOpen()) {
347
348       Handle(TDF_Delta) D = myUndoTransaction.Commit(Standard_True);
349       if (!(D.IsNull() || D->IsEmpty())) {
350         isDone = Standard_True;
351
352         myRedos.Clear(); // if we push an Undo we clear the redos
353         myUndos.Append(D); // New undos are at the end of the list
354         // Check  the limit to remove the oldest one
355         if (myUndos.Extent() > myUndoLimit) {
356 #ifdef SRN_DELTA_COMPACT
357           Handle(TDF_Delta) aDelta = myUndos.First();
358 #endif
359           myUndos.RemoveFirst();
360 #ifdef SRN_DELTA_COMPACT
361           if(myFromUndo == aDelta) {
362             //The oldest Undo delta coincides with `from` delta
363             if(myUndos.Extent() == 1) {   //There is the only Undo
364               myFromUndo.Nullify();
365               myFromRedo.Nullify();
366             }
367             else
368               myFromUndo = myUndos.First();
369           }
370 #endif
371         }
372       }
373
374     }
375
376     // deny or allow modifications according to transaction state
377     if(myOnlyTransactionModification) {
378       myData->AllowModification (myUndoTransaction.IsOpen() && myUndoLimit
379                                  ? Standard_True :Standard_False);
380     }
381   }
382   // Notify CDM_Application of the successful commit
383   if (isDone && IsOpened()) {
384     const Handle(TDocStd_Application) anAppli =
385       Handle(TDocStd_Application)::DownCast(Application());
386     if (!anAppli.IsNull())
387       anAppli -> OnCommitTransaction (this);
388   }
389   return isDone;
390 }
391
392
393 //=======================================================================
394 //function : AbortTransaction
395 //purpose  : Private method.
396 //=======================================================================
397
398 void TDocStd_Document::AbortTransaction()
399 {
400   myData->AllowModification(Standard_True);
401   
402   if (myUndoTransaction.IsOpen())
403     if (myUndoLimit != 0)
404       myUndoTransaction.Abort();
405
406   if (myIsNestedTransactionMode && myUndoFILO.Extent()) {
407     if (!myUndoFILO.First()->IsEmpty())
408       myData->Undo(myUndoFILO.First(),Standard_True);
409     myUndoFILO.RemoveFirst();
410     if (myUndoFILO.Extent())
411       myUndoTransaction.Open();
412   }
413   // deny or allow modifications according to transaction state
414   if (myOnlyTransactionModification) {
415     myData->AllowModification (myUndoTransaction.IsOpen() && myUndoLimit
416                                ? Standard_True :Standard_False);
417   }
418   // Notify CDM_Application of the event
419   if (IsOpened()) {
420     const Handle(TDocStd_Application) anAppli =
421       Handle(TDocStd_Application)::DownCast(Application());
422     if (!anAppli.IsNull())
423       anAppli -> OnAbortTransaction (this);
424   }
425 }
426
427
428 //=======================================================================
429 //function :OpenTransaction
430 //purpose  : Private method.
431 //=======================================================================
432
433 void TDocStd_Document::OpenTransaction()
434 {
435   myData->AllowModification(Standard_True);
436
437   // nested transaction mode
438   if (myIsNestedTransactionMode) {
439
440     if (myUndoTransaction.IsOpen()) {
441       Handle(TDF_Delta) D = myUndoTransaction.Commit(Standard_True);
442       Handle(TDocStd_CompoundDelta) aCompDelta =
443         Handle(TDocStd_CompoundDelta)::DownCast(myUndoFILO.First());
444       AppendDeltaToTheFirst(aCompDelta, D);
445     }
446     Standard_Integer aLastTime = myData->Time();
447     if (myUndoFILO.Extent())
448       aLastTime = myUndoFILO.First()->EndTime();
449     Handle(TDocStd_CompoundDelta) aCompoundDelta =
450       new TDocStd_CompoundDelta;
451     aCompoundDelta->Validity(aLastTime, aLastTime);
452     myUndoFILO.Prepend(aCompoundDelta);
453   } 
454
455   if (myUndoLimit != 0) myUndoTransaction.Open();
456
457   // deny or allow modifications according to transaction state
458   if (myOnlyTransactionModification) {
459     myData->AllowModification (myUndoTransaction.IsOpen() && myUndoLimit
460                                ? Standard_True :Standard_False);
461   }
462   // Notify CDM_Application of the event
463   if (IsOpened()) {
464     const Handle(TDocStd_Application) anAppli =
465       Handle(TDocStd_Application)::DownCast(Application());
466     if (!anAppli.IsNull())
467       anAppli -> OnOpenTransaction (this);
468   }
469 }
470
471 //=======================================================================
472 //function : SetUndoLimit
473 //purpose  : 
474 //=======================================================================
475
476 void TDocStd_Document::SetUndoLimit(const Standard_Integer L)
477 {  
478 #ifdef SRN_DELTA_COMPACT
479   myFromUndo.Nullify();  //Compaction has to aborted
480   myFromRedo.Nullify();
481 #endif
482
483   CommitTransaction ();
484   myUndoLimit = (L > 0) ? L : 0;
485   Standard_Integer n = myUndos.Extent() - myUndoLimit;
486   while (n > 0) {
487     myUndos.RemoveFirst();
488     --n;
489   }
490   // deny or allow modifications according to transaction state
491   if(myOnlyTransactionModification) {
492     myData->AllowModification(myUndoTransaction.IsOpen() && myUndoLimit
493                               ? Standard_True :Standard_False);
494   }
495   //OpenTransaction(); dp 15/10/99
496 }
497
498 //=======================================================================
499 //function : GetUndoLimit
500 //purpose  : 
501 //=======================================================================
502
503 Standard_Integer TDocStd_Document::GetUndoLimit() const
504 {
505   return myUndoLimit;
506 }
507
508 //=======================================================================
509 //function : Undos
510 //purpose  : 
511 //=======================================================================
512
513 Standard_Integer TDocStd_Document::GetAvailableUndos() const
514 {
515   return myUndos.Extent();
516 }
517
518 //=======================================================================
519 //function : ClearUndos
520 //purpose  : 
521 //=======================================================================
522
523 void TDocStd_Document::ClearUndos()
524 {
525   myUndos.Clear();
526   myRedos.Clear();
527 #ifdef SRN_DELTA_COMPACT
528   myFromRedo.Nullify();
529   myFromUndo.Nullify();
530 #endif
531 }
532
533 //=======================================================================
534 //function : ClearRedos
535 //purpose  : 
536 //=======================================================================
537
538 void TDocStd_Document::ClearRedos()
539 {
540   myRedos.Clear();
541 #ifdef SRN_DELTA_COMPACT
542   myFromRedo.Nullify();
543 #endif
544 }
545
546 //=======================================================================
547 //function : Undo
548 //purpose  : 
549 // Some important notice:
550 // 1) The most recent undo delta is at the end of the list.
551 // 2) Removing the LAST item of a list is tedious, but it is done only on
552 //    Undo. Remove first is done at each command if the limit is reached!
553 // 3) To make fun, the redos are not like the undos: the most recent delta
554 //    is at the beginning! Like this, it is easier to remove it after use.
555 //=======================================================================
556 Standard_Boolean TDocStd_Document::Undo() 
557 {
558   // Don't call NewCommand(), because it may commit Interactive Attributes
559   // and generate a undesirable Delta!
560
561   Standard_Boolean isOpened = myUndoTransaction.IsOpen();
562   Standard_Boolean undoDone = Standard_False;
563   //TDF_Label currentObjectLabel = CurrentLabel (); //Sauve pour usage ulterieur.
564
565   if (!myUndos.IsEmpty()) {
566     // Reset the transaction
567     AbortTransaction();
568
569     // only for nested transaction mode
570     while(myIsNestedTransactionMode && myUndoFILO.Extent())
571       AbortTransaction();
572
573     // allow modifications
574     myData->AllowModification(Standard_True);
575
576     // Apply the Undo
577     // should test the applicability before.
578 #ifdef OCCT_DEBUG_DELTA
579     std::cout<<"DF before Undo =================================="<<std::endl; TDF_Tool::DeepDump(std::cout,myData);
580 #endif
581     Handle(TDF_Delta) D = myData->Undo(myUndos.Last(),Standard_True);
582     D->SetName(myUndos.Last()->Name());
583 #ifdef OCCT_DEBUG_DELTA
584     std::cout<<"DF after Undo =================================="<<std::endl; TDF_Tool::DeepDump(std::cout,myData);
585 #endif
586     // Push the redo
587     myRedos.Prepend(D);
588     // Remove the last Undo
589     TDocStd_List_RemoveLast(myUndos);
590     undoDone = Standard_True;
591   }
592
593   if (isOpened && undoDone) OpenTransaction();
594
595   // deny or allow modifications according to transaction state
596   if(myOnlyTransactionModification) {
597     myData->AllowModification(myUndoTransaction.IsOpen() && myUndoLimit
598                               ? Standard_True :Standard_False);
599   }
600   
601   return undoDone;
602 }
603
604 //=======================================================================
605 //function : GetAvailableRedos
606 //purpose  : 
607 //=======================================================================
608
609 Standard_Integer TDocStd_Document:: GetAvailableRedos() const
610 {
611   // should test the applicability before.
612   return myRedos.Extent();
613 }
614
615 //=======================================================================
616 //function : Redo
617 //purpose  : 
618 //=======================================================================
619 Standard_Boolean TDocStd_Document::Redo() 
620 {
621   Standard_Boolean isOpened = myUndoTransaction.IsOpen();
622   Standard_Boolean undoDone = Standard_False;
623   if (!myRedos.IsEmpty()) {
624     // should test the applicability before.
625     // Reset the transaction
626     AbortTransaction();
627
628     // only for nested transaction mode
629     while(myIsNestedTransactionMode && myUndoFILO.Extent())
630       AbortTransaction();
631
632     // allow modifications
633     myData->AllowModification(Standard_True);
634
635     // Apply the Redo
636 #ifdef OCCT_DEBUG_DELTA
637     std::cout<<"DF before Redo =================================="<<std::endl; TDF_Tool::DeepDump(std::cout,myData);
638 #endif
639     Handle(TDF_Delta) D = myData->Undo(myRedos.First(),Standard_True);
640     D->SetName(myRedos.First()->Name());
641 #ifdef OCCT_DEBUG_DELTA
642     std::cout<<"DF after Redo =================================="<<std::endl; TDF_Tool::DeepDump(std::cout,myData);
643 #endif
644     // Push the redo of the redo as an undo (got it !)
645     myUndos.Append(D);
646     // remove the Redo from the head
647     myRedos.RemoveFirst();
648     undoDone = Standard_True;
649   }
650   
651   if (isOpened && undoDone) OpenTransaction();
652
653   // deny or allow modifications according to transaction state
654   if(myOnlyTransactionModification) {
655     myData->AllowModification(myUndoTransaction.IsOpen() && myUndoLimit
656                               ? Standard_True :Standard_False);
657   }
658
659   return undoDone;
660 }
661
662 //=======================================================================
663 //function : UpdateReferences
664 //purpose  : 
665 //=======================================================================
666
667 void TDocStd_Document::UpdateReferences(const TCollection_AsciiString& aDocEntry) 
668 {
669
670   TDF_AttributeList aRefList;
671   TDocStd_XLink* xRefPtr;
672   for (TDocStd_XLinkIterator xItr (this); xItr.More(); xItr.Next()) {
673     xRefPtr = xItr.Value();
674     if (xRefPtr->DocumentEntry() == aDocEntry) {
675       aRefList.Append(xRefPtr->Update());
676     }
677   }
678   TDF_ListIteratorOfAttributeList It(aRefList);
679   for (;It.More();It.Next()) {
680     //     // mise a jour import
681     SetModified(It.Value()->Label());
682   }
683 }
684
685
686 //=======================================================================
687 //function : GetUndos
688 //purpose  : 
689 //=======================================================================
690
691 const TDF_DeltaList& TDocStd_Document::GetUndos() const 
692 {
693   return myUndos;
694 }
695
696
697 //=======================================================================
698 //function : GetRedos
699 //purpose  : 
700 //=======================================================================
701
702 const TDF_DeltaList& TDocStd_Document::GetRedos() const 
703 {
704   return myRedos;
705 }
706
707 //=======================================================================
708 //function : InitDeltaCompaction
709 //purpose  : 
710 //=======================================================================
711
712 Standard_Boolean TDocStd_Document::InitDeltaCompaction()
713 {
714 #ifdef SRN_DELTA_COMPACT
715   if (myUndoLimit == 0 || myUndos.Extent() == 0) {
716     myFromRedo.Nullify();
717     myFromUndo.Nullify();
718     return Standard_False; //No Undos to compact
719   }
720
721   myFromRedo.Nullify();
722
723   myFromUndo = myUndos.Last();
724   if(myRedos.Extent() > 0) myFromRedo = myRedos.First();
725 #endif
726   return Standard_True;
727 }
728
729 //=======================================================================
730 //function : PerformDeltaCompaction
731 //purpose  : 
732 //=======================================================================
733
734 Standard_Boolean TDocStd_Document::PerformDeltaCompaction()  
735
736 #ifdef SRN_DELTA_COMPACT
737   if(myFromUndo.IsNull()) return Standard_False;  //Redo can be Null for this operation 
738
739   TDF_DeltaList aList; 
740   Handle(TDocStd_CompoundDelta) aCompoundDelta = new TDocStd_CompoundDelta; 
741   TDF_ListIteratorOfDeltaList anIterator(myUndos); 
742   TDF_ListIteratorOfAttributeDeltaList aDeltasIterator;
743   TDocStd_LabelIDMapDataMap aMap; 
744   Standard_Boolean isFound = Standard_False, isTimeSet = Standard_False; 
745
746   //Process Undos
747
748   for(; anIterator.More(); anIterator.Next()) { 
749     if(!isFound) { 
750       if(myFromUndo == anIterator.Value()) isFound = Standard_True; 
751       aList.Append(anIterator.Value());  //Fill the list of deltas that precede compound delta 
752       continue;
753     } 
754
755     if(!isTimeSet) {  //Set begin and end time when the compound delta is valid
756       aCompoundDelta->Validity(anIterator.Value()->BeginTime(), myUndos.Last()->EndTime());
757       isTimeSet = Standard_True;
758     } 
759     
760     aDeltasIterator.Initialize(anIterator.Value()->AttributeDeltas());
761     for(; aDeltasIterator.More(); aDeltasIterator.Next()) {   
762       if(!aMap.IsBound(aDeltasIterator.Value()->Label())) {
763         TDF_IDMap* pIDMap = new TDF_IDMap();
764         aMap.Bind(aDeltasIterator.Value()->Label(), *pIDMap);
765         delete pIDMap;
766         }
767       if(aMap(aDeltasIterator.Value()->Label()).Add(aDeltasIterator.Value()->ID())) //The attribute is not 
768         aCompoundDelta->AddAttributeDelta(aDeltasIterator.Value());                 //already in the delta
769     }
770   } 
771
772   myUndos.Clear(); 
773   myUndos.Assign(aList); 
774   myUndos.Append(aCompoundDelta); 
775
776   //Process Redos
777
778   if(myFromRedo.IsNull()) {
779     myRedos.Clear();
780     return Standard_True;
781   }
782
783   aList.Clear();
784
785   for(anIterator.Initialize(myRedos); anIterator.More(); anIterator.Next()) { 
786     aList.Append(anIterator.Value()); 
787     if(anIterator.Value() == myFromRedo) break;
788   }
789
790   myRedos.Clear();
791   myRedos.Assign(aList); 
792 #endif
793   return Standard_True; 
794
795
796
797 //=======================================================================
798 //function : StorageFormat
799 //purpose  : 
800 //=======================================================================
801
802 TCollection_ExtendedString TDocStd_Document::StorageFormat() const 
803 {
804   return myStorageFormat;
805 }
806
807
808 //=======================================================================
809 //function : ChangeStorageFormat
810 //purpose  : 
811 //=======================================================================
812
813 void TDocStd_Document::ChangeStorageFormat (const TCollection_ExtendedString& newStorageFormat) 
814 {
815   if (newStorageFormat != myStorageFormat) {
816     myStorageFormat = newStorageFormat;
817     myResourcesAreLoaded = Standard_False;
818     CDM_Document::LoadResources ();
819   }
820 }
821
822
823
824
825 //=======================================================================
826 //function : Recompute
827 //purpose  : 
828 //=======================================================================
829
830 void TDocStd_Document::Recompute ()
831 {
832   if (IsValid()) return;
833   // find the top function and execute it
834   //  Handle(TDesign_Function) F;
835   //  if (Main().FindAttribute(TDesign_Function::GetID(),F)) {
836   // TFunction_Solver slv;
837   // slv.SetTouched(GetModified());
838   // slv.ExecuteFrom(F);
839   PurgeModified();
840 }
841
842 //=======================================================================
843 //function : AppendDeltaToTheFirst
844 //purpose  : Appends delta to the first delta in the myUndoFILO
845 //=======================================================================
846
847 void TDocStd_Document::AppendDeltaToTheFirst
848   (const Handle(TDocStd_CompoundDelta)& theDelta1,
849    const Handle(TDF_Delta)& theDelta2)
850 {
851   if(theDelta2->IsEmpty()) return;
852   TDocStd_LabelIDMapDataMap aMap; 
853     
854   TDF_ListIteratorOfAttributeDeltaList aDeltasIterator1
855     (theDelta1->AttributeDeltas());
856   for(; aDeltasIterator1.More(); aDeltasIterator1.Next()) {   
857     TDF_Label aLabel = aDeltasIterator1.Value()->Label();
858     if(!aMap.IsBound(aLabel)) {
859       TDF_IDMap aTmpIDMap;
860       aMap.Bind(aLabel, aTmpIDMap);
861     }
862     Standard_GUID anID = aDeltasIterator1.Value()->ID();
863     TDF_IDMap& anIDMap = aMap.ChangeFind(aLabel);
864     anIDMap.Add(anID);
865   }
866   
867   theDelta1->Validity(theDelta1->BeginTime(), theDelta2->EndTime());
868   TDF_ListIteratorOfAttributeDeltaList aDeltasIterator2
869     (theDelta2->AttributeDeltas());
870   for(; aDeltasIterator2.More(); aDeltasIterator2.Next()) {   
871     TDF_Label aLabel = aDeltasIterator2.Value()->Label();
872     Standard_GUID anID = aDeltasIterator2.Value()->ID();
873     if(aMap.IsBound(aLabel)) {
874       const TDF_IDMap& anIDMap = aMap.Find(aLabel);
875       if(anIDMap.Contains(anID)) continue;
876     }
877     theDelta1->AddAttributeDelta(aDeltasIterator2.Value());
878   }
879 }
880
881 //=======================================================================
882 //function : RemoveFirstUndo
883 //purpose  : 
884 //=======================================================================
885 void TDocStd_Document::RemoveFirstUndo() {
886   if (myUndos.IsEmpty()) return;
887   myUndos.RemoveFirst();
888 }
889
890 //=======================================================================
891 //function : BeforeClose
892 //purpose  : 
893 //=======================================================================
894 void TDocStd_Document::BeforeClose() 
895 {
896   SetModificationMode(Standard_False);
897   AbortTransaction();
898   if(myIsNestedTransactionMode)
899          myUndoFILO.Clear();
900   ClearUndos();
901 }
902
903 //=======================================================================
904 //function : StorageFormatVersion
905 //purpose  : 
906 //=======================================================================
907 TDocStd_FormatVersion TDocStd_Document::StorageFormatVersion() const
908 {
909   return myStorageFormatVersion;
910 }
911
912 //=======================================================================
913 //function : ChangeStorageFormatVersion
914 //purpose  : Sets <theVersion> of the format to be used to store the document
915 //=======================================================================
916 void TDocStd_Document::ChangeStorageFormatVersion(const TDocStd_FormatVersion theVersion)
917 {
918   myStorageFormatVersion = theVersion;
919 }
920
921 //=======================================================================
922 //function : CurrentStorageFormatVersion
923 //purpose  : Returns current storage format version of the document.
924 //=======================================================================
925 TDocStd_FormatVersion TDocStd_Document::CurrentStorageFormatVersion()
926 {
927   return TDocStd_FormatVersion_CURRENT;
928 }
929
930 //=======================================================================
931 //function : DumpJson
932 //purpose  : 
933 //=======================================================================
934 void TDocStd_Document::DumpJson (Standard_OStream& theOStream, Standard_Integer theDepth) const
935 {
936   OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream)
937
938   OCCT_DUMP_BASE_CLASS (theOStream, theDepth, CDM_Document)
939   
940   OCCT_DUMP_FIELD_VALUE_STRING (theOStream, myStorageFormat)
941   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, IsSaved())
942   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, IsChanged())
943   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, IsEmpty())
944   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, IsValid())
945   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, GetAvailableUndos())
946   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, GetAvailableRedos())
947   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, HasOpenCommand())
948
949   for (TDF_DeltaList::Iterator anUndoIt (myUndos); anUndoIt.More(); anUndoIt.Next())
950   {
951     const Handle(TDF_Delta)& anUndo = anUndoIt.Value();
952     OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, anUndo.get())
953   }
954
955   for (TDF_DeltaList::Iterator aRedoIt (myRedos); aRedoIt.More(); aRedoIt.Next())
956   {
957     const Handle(TDF_Delta)& aRedo = aRedoIt.Value();
958     OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, aRedo.get())
959   }
960
961   OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, myData.get())
962   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myUndoLimit)
963   OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, &myUndoTransaction)
964   OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, myFromUndo.get())
965   OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, myFromRedo.get())
966   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, mySaveTime)
967   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myIsNestedTransactionMode)
968
969   for (TDF_DeltaList::Iterator anUndoFILOIt (myUndoFILO); anUndoFILOIt.More(); anUndoFILOIt.Next())
970   {
971     const Handle(TDF_Delta)& anUndoFILO = anUndoFILOIt.Value();
972     OCCT_DUMP_FIELD_VALUES_DUMPED (theOStream, theDepth, anUndoFILO.get())
973   }
974
975   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myOnlyTransactionModification)
976   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, mySaveEmptyLabels)
977   OCCT_DUMP_FIELD_VALUE_NUMERICAL(theOStream,  myStorageFormatVersion)
978 }