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