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