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