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