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