Test for 0022778: Bug in BRepMesh
[occt.git] / src / TDocStd / TDocStd_MultiTransactionManager.cxx
CommitLineData
b311480e 1// Created on: 2002-11-19
2// Created by: Vladimir ANIKIN
3// Copyright (c) 2002-2012 OPEN CASCADE SAS
4//
5// The content of this file is subject to the Open CASCADE Technology Public
6// License Version 6.5 (the "License"). You may not use the content of this file
7// except in compliance with the License. Please obtain a copy of the License
8// at http://www.opencascade.org and read it completely before using this file.
9//
10// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12//
13// The Original Code and all software distributed under the License is
14// distributed on an "AS IS" basis, without warranty of any kind, and the
15// Initial Developer hereby disclaims all such warranties, including without
16// limitation, any warranties of merchantability, fitness for a particular
17// purpose or non-infringement. Please see the License for the specific terms
18// and conditions governing the rights and limitations under the License.
19
7fd59977 20
21#include <TDocStd_MultiTransactionManager.ixx>
22#include <TDocStd_Document.hxx>
23#include <TDocStd_ApplicationDelta.hxx>
24
25//=======================================================================
26//function : TDocStd_MultiTransactionManager
27//purpose : Constructor
28//=======================================================================
29
30TDocStd_MultiTransactionManager::TDocStd_MultiTransactionManager ()
31{
32 myUndoLimit = 0;
33 myOpenTransaction = Standard_False;
34 myIsNestedTransactionMode = Standard_False;
35 myOnlyTransactionModification = Standard_False;
36}
37
38//=======================================================================
39//function : SetUndoLimit
40//purpose :
41//=======================================================================
42
43void TDocStd_MultiTransactionManager::SetUndoLimit(const Standard_Integer theLimit)
44{
45 myUndoLimit = theLimit;
46
47 CommitCommand ();
48
49 Standard_Integer n = myUndos.Length() - myUndoLimit;
50 while (n > 0) {
51 RemoveLastUndo();
52 --n;
53 }
54
55 Standard_Integer i;
56 for(i = myDocuments.Length(); i > 0; i--)
57 myDocuments.Value(i)->SetUndoLimit(myUndoLimit);
58
59}
60
61//=======================================================================
62//function : Undo
63//purpose :
64//=======================================================================
65
66void TDocStd_MultiTransactionManager::Undo()
67{
68 if (myUndos.IsEmpty()) return;
69 const TDocStd_SequenceOfDocument& docs = myUndos.First()->GetDocuments();
70 Standard_Integer i;
71 for (i = docs.Length(); i > 0; i--) {
72 Handle(TDocStd_Document) doc = docs.Value(i);
73 if (doc.IsNull() || doc->GetAvailableUndos() == 0) continue;
74 doc->Undo();
75 }
76 myRedos.Prepend(myUndos.First());
77 myUndos.Remove(1);
78 myOpenTransaction = Standard_False;
79}
80
81//=======================================================================
82//function : Redo
83//purpose :
84//=======================================================================
85
86void TDocStd_MultiTransactionManager::Redo() {
87 if (myRedos.IsEmpty()) return;
88 const TDocStd_SequenceOfDocument& docs = myRedos.First()->GetDocuments();
89 Standard_Integer i;
90 for (i = docs.Length(); i > 0; i--) {
91 Handle(TDocStd_Document) doc = docs.Value(i);
92 if (doc.IsNull() || doc->GetAvailableRedos() == 0) continue;
93 doc->Redo();
94 }
95 myUndos.Prepend(myRedos.First());
96 myRedos.Remove(1);
97 myOpenTransaction = Standard_False;
98}
99
100//=======================================================================
101//function : OpenCommand
102//purpose :
103//=======================================================================
104
105void TDocStd_MultiTransactionManager::OpenCommand() {
106 if (myOpenTransaction) {
107#ifdef DEB
108 cout << "TDocStd_MultiTransactionManager::OpenCommand(): "
109 "Can't start new application transaction while a "
110 "previous one is not commited or aborted" << endl;
111#endif
112 Standard_Failure::Raise("Can't start new application transaction"
113 "while a previous one is not commited or aborted");
114 }
115 myOpenTransaction = Standard_True;
116 Standard_Integer i;
117 for(i = myDocuments.Length(); i > 0; i--) {
118 while(myDocuments.Value(i)->HasOpenCommand())
119 myDocuments.Value(i)->AbortCommand();
120 myDocuments.Value(i)->OpenCommand();
121 }
122}
123
124//=======================================================================
125//function : AbortCommand
126//purpose :
127//=======================================================================
128
129void TDocStd_MultiTransactionManager::AbortCommand() {
130 myOpenTransaction = Standard_False;
131 Standard_Integer i;
132 for(i = myDocuments.Length(); i > 0; i--) {
133 while(myDocuments.Value(i)->HasOpenCommand())
134 myDocuments.Value(i)->AbortCommand();
135 }
136}
137
138//=======================================================================
139//function : CommitCommand
140//purpose :
141//=======================================================================
142
143Standard_Boolean TDocStd_MultiTransactionManager::CommitCommand()
144{
145 Handle(TDocStd_ApplicationDelta) aDelta = new TDocStd_ApplicationDelta;
146 Standard_Boolean isCommited = Standard_False;
147 Standard_Integer i;
148 for(i = myDocuments.Length(); i > 0; i--) {
149 isCommited = Standard_False;
150 while(myDocuments.Value(i)->HasOpenCommand())
151 if (myDocuments.Value(i)->CommitCommand())
152 isCommited = Standard_True;
153 if(isCommited) {
154 aDelta->GetDocuments().Append(myDocuments.Value(i));
155 }
156 }
157
158 if (aDelta->GetDocuments().Length()) {
159 myUndos.Prepend(aDelta);
160 if (myUndos.Length() > myUndoLimit) {
161 RemoveLastUndo();
162 }
163 myRedos.Clear();
164 isCommited = Standard_True;
165 }
166 myOpenTransaction = Standard_False;
167 return isCommited;
168}
169
170//=======================================================================
171//function : CommitCommand
172//purpose :
173//=======================================================================
174
175Standard_Boolean TDocStd_MultiTransactionManager::CommitCommand
176 (const TCollection_ExtendedString& theName)
177{
178 Standard_Boolean isCommited = CommitCommand();
179 if (isCommited && myUndos.Length())
180 myUndos.First()->SetName(theName);
181 return isCommited;
182}
183
184//=======================================================================
185//function : DumpTransaction
186//purpose :
187//=======================================================================
188
189void TDocStd_MultiTransactionManager::DumpTransaction(Standard_OStream& anOS) const
190{
191 Standard_Integer i;
192 if(myDocuments.Length() == 0)
193 anOS << "Manager is empty" << endl;
194 else {
195 if(myDocuments.Length() == 1)
196 anOS << "There is one document ( ";
197 else
198 anOS << "There are " << myDocuments.Length() << " documents ( ";
199 for(i = 1; i <= myDocuments.Length(); i++) {
200 Handle(Standard_Transient) aDoc = myDocuments.Value(i);
201 anOS << "\"" << (Standard_Transient*)aDoc;
202 anOS << "\" ";
203 }
204 anOS << ") in the manager " << endl;
205
206 if(myIsNestedTransactionMode)
207 anOS << "Nested transaction mode is on" << endl;
208 else
209 anOS << "Nested transaction mode is off" << endl;
210
211 anOS << " " << endl;
212 }
213
214 for (i = myUndos.Length(); i > 0; i--) {
215 Handle(TDocStd_ApplicationDelta) delta = myUndos.Value(i);
216 anOS<<" Undo: ";
217 delta->Dump(anOS);
218 if (i == 1) {
219 anOS<<" < Last action"<<endl;
220 } else {
221 anOS<<endl;
222 }
223 }
224 for (i = 1; i <= myRedos.Length(); i++) {
225 Handle(TDocStd_ApplicationDelta) delta = myRedos.Value(i);
226 anOS<<" Redo: ";
227 delta->Dump(anOS);
228 anOS<<endl;
229 }
230}
231
232//=======================================================================
233//function : RemoveLastUndo
234//purpose :
235//=======================================================================
236
237void TDocStd_MultiTransactionManager::RemoveLastUndo()
238{
239 if(myUndos.Length() == 0) return;
240 const TDocStd_SequenceOfDocument& docs = myUndos.Last()->GetDocuments();
241 Standard_Integer i;
242 for (i = 1; i <= docs.Length(); i++) {
243 docs.Value(i)->RemoveFirstUndo();
244 }
245 myUndos.Remove(myUndos.Length());
246}
247
248//=======================================================================
249//function : AddDocument
250//purpose :
251//=======================================================================
252
253void TDocStd_MultiTransactionManager::AddDocument
254 (const Handle(TDocStd_Document)& theDoc)
255{
256 Standard_Integer i;
257 for(i = myDocuments.Length(); i > 0; i--)
258 if(myDocuments.Value(i) == theDoc)
259 return; // the document is already added to the list
260
261 if(theDoc->IsNestedTransactionMode() !=
262 myIsNestedTransactionMode)
263 theDoc->SetNestedTransactionMode(myIsNestedTransactionMode);
264
265 theDoc->SetModificationMode(myOnlyTransactionModification);
266
267 myDocuments.Append(theDoc);
268 theDoc->SetUndoLimit(myUndoLimit);
269 if(myOpenTransaction) {
270 if(!theDoc->HasOpenCommand())
271 theDoc->OpenCommand();
272 }
273 else {
274 if(theDoc->HasOpenCommand())
275 theDoc->CommitCommand();
276 }
277 theDoc->ClearUndos();
278 theDoc->ClearRedos();
279}
280
281//=======================================================================
282//function : RemoveDocument
283//purpose :
284//=======================================================================
285
286void TDocStd_MultiTransactionManager::RemoveDocument
287 (const Handle(TDocStd_Document)& theDoc)
288{
289 Standard_Integer i;
290 for(i = myDocuments.Length(); i > 0; i--) {
291 if(myDocuments.Value(i) == theDoc)
292 myDocuments.Remove(i);
293 }
294 for (i = myUndos.Length(); i > 0; i--) {
295 Handle(TDocStd_ApplicationDelta) delta = myUndos.Value(i);
296 TDocStd_SequenceOfDocument& docs = delta->GetDocuments();
297 for(Standard_Integer j = docs.Length(); j > 0; j--) {
298 if(docs.Value(j) == theDoc) {
299 docs.Remove(j);
300 if(docs.Length() == 0)
301 myUndos.Remove(i);
302 }
303 }
304 }
305 for (i = myRedos.Length(); i > 0; i--) {
306 Handle(TDocStd_ApplicationDelta) delta = myRedos.Value(i);
307 TDocStd_SequenceOfDocument& docs = delta->GetDocuments();
308 for(Standard_Integer j = docs.Length(); j > 0; j--) {
309 if(docs.Value(j) == theDoc) {
310 docs.Remove(j);
311 if(docs.Length() == 0)
312 myRedos.Remove(i);
313 }
314 }
315 }
316}
317
318//=======================================================================
319//function : SetNestedTransactionMode
320//purpose :
321//=======================================================================
322
323void TDocStd_MultiTransactionManager::SetNestedTransactionMode
324 (const Standard_Boolean isAllowed)
325{
326 myIsNestedTransactionMode = isAllowed;
327 Standard_Integer i;
328 for(i = myDocuments.Length(); i > 0; i--) {
329 if(myDocuments.Value(i)->IsNestedTransactionMode() != myIsNestedTransactionMode)
330 myDocuments.Value(i)->SetNestedTransactionMode(myIsNestedTransactionMode);
331 }
332}
333
334//=======================================================================
335//function : SetModificationMode
336//purpose : if theTransactionOnly is True changes is denied outside transactions
337//=======================================================================
338
339void TDocStd_MultiTransactionManager::SetModificationMode
340 (const Standard_Boolean theTransactionOnly)
341{
342 myOnlyTransactionModification = theTransactionOnly;
343
344 Standard_Integer i;
345 for(i = myDocuments.Length(); i > 0; i--) {
346 myDocuments.Value(i)->SetModificationMode(myOnlyTransactionModification);
347 }
348}
349
350//=======================================================================
351//function : ClearUndos
352//purpose :
353//=======================================================================
354
355void TDocStd_MultiTransactionManager::ClearUndos()
356{
357 AbortCommand();
358
359 myUndos.Clear();
360 Standard_Integer i;
361 for(i = myDocuments.Length(); i > 0; i--) {
362 myDocuments.Value(i)->ClearUndos();
363 }
364}
365
366//=======================================================================
367//function : ClearRedos
368//purpose :
369//=======================================================================
370
371void TDocStd_MultiTransactionManager::ClearRedos()
372{
373 AbortCommand();
374
375 myRedos.Clear();
376 Standard_Integer i;
377 for(i = myDocuments.Length(); i > 0; i--) {
378 myDocuments.Value(i)->ClearRedos();
379 }
380}
381
382
383