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 |
44 | IMPLEMENT_STANDARD_RTTIEXT(TDocStd_Document,CDM_Document) |
45 | |
7fd59977 |
46 | // List should have a RemoveLast... |
47 | #define TDocStd_List_RemoveLast(theList) \ |
48 | TDF_ListIteratorOfDeltaList it(theList); \ |
49 | Standard_Integer i,n = theList.Extent(); \ |
50 | for (i = 1; i < n; i++) it.Next(); \ |
51 | theList.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 | |
64 | Handle(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 |
79 | TDocStd_Document::TDocStd_Document(const TCollection_ExtendedString& aStorageFormat) : |
7fd59977 |
80 | myStorageFormat(aStorageFormat), |
81 | myData (new TDF_Data()), |
82 | myUndoLimit(0), |
158f2931 |
83 | myUndoTransaction ("UNDO"), |
7fd59977 |
84 | mySaveTime(0), |
030ba648 |
85 | myIsNestedTransactionMode(0), |
716cf4d9 |
86 | mySaveEmptyLabels(Standard_False), |
87 | myStorageFormatVersion(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 | |
104 | Standard_Boolean TDocStd_Document::IsSaved() const |
105 | { |
106 | return CDM_Document::IsStored(); |
107 | } |
108 | |
109 | |
110 | //======================================================================= |
111 | //function : GetName |
112 | //purpose : |
113 | //======================================================================= |
114 | |
115 | TCollection_ExtendedString TDocStd_Document::GetName () const |
116 | { |
117 | return CDM_Document::MetaData()->Name(); |
118 | } |
119 | |
120 | //======================================================================= |
121 | //function : GetPath |
122 | //purpose : |
123 | //======================================================================= |
124 | |
125 | TCollection_ExtendedString TDocStd_Document::GetPath () const |
126 | { |
127 | return CDM_Document::MetaData()->Path(); |
128 | } |
129 | |
130 | |
131 | //======================================================================= |
132 | //function : SetData |
133 | //purpose : |
134 | //======================================================================= |
135 | |
136 | void 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 | |
147 | Handle(TDF_Data) TDocStd_Document::GetData () const |
148 | { |
149 | return myData; |
150 | } |
151 | |
152 | //======================================================================= |
153 | //function : Main |
154 | //purpose : |
155 | //======================================================================= |
156 | |
157 | TDF_Label TDocStd_Document::Main () const |
158 | { |
159 | return myData->Root().FindChild(1,Standard_True); |
160 | } |
161 | |
162 | //======================================================================= |
163 | //function : IsEmpty |
164 | //purpose : |
165 | //======================================================================= |
166 | |
167 | Standard_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 | |
178 | Standard_Boolean TDocStd_Document::IsValid() const |
179 | { |
180 | return TDocStd_Modified::IsEmpty(Main()); |
181 | } |
182 | |
183 | //======================================================================= |
184 | //function : SetModified |
185 | //purpose : |
186 | //======================================================================= |
187 | |
188 | void 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 | |
207 | void TDocStd_Document::PurgeModified() |
208 | { |
209 | TDocStd_Modified::Clear(Main()); |
210 | } |
211 | |
212 | //======================================================================= |
213 | //function : GetModified |
214 | //purpose : |
215 | //======================================================================= |
216 | |
217 | const 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 | |
229 | void 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 | |
246 | void 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 | //======================================================================= |
267 | Standard_Boolean TDocStd_Document::HasOpenCommand() const |
268 | { |
269 | return myUndoTransaction.IsOpen(); |
270 | } |
271 | |
272 | //======================================================================= |
273 | //function : OpenCommand |
274 | //purpose : |
275 | //======================================================================= |
276 | |
277 | void 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 | |
291 | Standard_Boolean TDocStd_Document::CommitCommand () |
292 | { |
293 | return CommitTransaction(); |
294 | } |
295 | |
296 | |
297 | //======================================================================= |
298 | //function : AbortCommand |
299 | //purpose : |
300 | //======================================================================= |
301 | |
302 | void TDocStd_Document::AbortCommand () |
303 | { |
304 | AbortTransaction(); |
305 | } |
306 | |
307 | |
308 | //======================================================================= |
309 | //function : CommitTransaction |
310 | //purpose : Private method. |
311 | //======================================================================= |
312 | |
313 | Standard_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 | |
401 | void 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 | |
436 | void 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 | |
479 | void 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 | |
506 | Standard_Integer TDocStd_Document::GetUndoLimit() const |
507 | { |
508 | return myUndoLimit; |
509 | } |
510 | |
511 | //======================================================================= |
512 | //function : Undos |
513 | //purpose : |
514 | //======================================================================= |
515 | |
516 | Standard_Integer TDocStd_Document::GetAvailableUndos() const |
517 | { |
518 | return myUndos.Extent(); |
519 | } |
520 | |
521 | //======================================================================= |
522 | //function : ClearUndos |
523 | //purpose : |
524 | //======================================================================= |
525 | |
526 | void 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 | |
541 | void 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 | //======================================================================= |
559 | Standard_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 | |
612 | Standard_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 | //======================================================================= |
622 | Standard_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 | |
670 | void 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 | |
694 | const TDF_DeltaList& TDocStd_Document::GetUndos() const |
695 | { |
696 | return myUndos; |
697 | } |
698 | |
699 | |
700 | //======================================================================= |
701 | //function : GetRedos |
702 | //purpose : |
703 | //======================================================================= |
704 | |
705 | const TDF_DeltaList& TDocStd_Document::GetRedos() const |
706 | { |
707 | return myRedos; |
708 | } |
709 | |
710 | //======================================================================= |
711 | //function : InitDeltaCompaction |
712 | //purpose : |
713 | //======================================================================= |
714 | |
715 | Standard_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 | |
737 | Standard_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 | |
805 | TCollection_ExtendedString TDocStd_Document::StorageFormat() const |
806 | { |
807 | return myStorageFormat; |
808 | } |
809 | |
810 | |
811 | //======================================================================= |
812 | //function : ChangeStorageFormat |
813 | //purpose : |
814 | //======================================================================= |
815 | |
816 | void 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 | |
833 | void 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 | |
850 | void 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 | //======================================================================= |
888 | void TDocStd_Document::RemoveFirstUndo() { |
889 | if (myUndos.IsEmpty()) return; |
890 | myUndos.RemoveFirst(); |
891 | } |
892 | |
1c9cffdb |
893 | //======================================================================= |
894 | //function : BeforeClose |
895 | //purpose : |
896 | //======================================================================= |
897 | void 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 | //======================================================================= |
910 | TDocStd_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 | //======================================================================= |
919 | void 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 | //======================================================================= |
928 | TDocStd_FormatVersion TDocStd_Document::CurrentStorageFormatVersion() |
929 | { |
930 | return TDocStd_FormatVersion_CURRENT; |
931 | } |
932 | |
bc73b006 |
933 | //======================================================================= |
934 | //function : DumpJson |
935 | //purpose : |
936 | //======================================================================= |
937 | void 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 | } |