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 | |
15 | TDocStd_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 | |
28 | void 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 | |
51 | void 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 | |
71 | void 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 | |
90 | void 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 | |
114 | void 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 | |
128 | Standard_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 | |
160 | Standard_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 | |
174 | void 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 | |
222 | void 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 | |
238 | void 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 | |
271 | void 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 | |
308 | void 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 | |
324 | void 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 | |
340 | void 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 | |
356 | void 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 | |