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