1 // Created on: 2002-11-19
2 // Created by: Vladimir ANIKIN
3 // Copyright (c) 2002-2014 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
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
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.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <TDocStd_MultiTransactionManager.hxx>
18 #include <Standard_Type.hxx>
19 #include <TCollection_ExtendedString.hxx>
20 #include <TDocStd_ApplicationDelta.hxx>
21 #include <TDocStd_Document.hxx>
23 IMPLEMENT_STANDARD_RTTIEXT(TDocStd_MultiTransactionManager,Standard_Transient)
25 //=======================================================================
26 //function : TDocStd_MultiTransactionManager
27 //purpose : Constructor
28 //=======================================================================
29 TDocStd_MultiTransactionManager::TDocStd_MultiTransactionManager ()
32 myOpenTransaction = Standard_False;
33 myIsNestedTransactionMode = Standard_False;
34 myOnlyTransactionModification = Standard_False;
37 //=======================================================================
38 //function : SetUndoLimit
40 //=======================================================================
42 void TDocStd_MultiTransactionManager::SetUndoLimit(const Standard_Integer theLimit)
44 myUndoLimit = theLimit;
48 Standard_Integer n = myUndos.Length() - myUndoLimit;
55 for(i = myDocuments.Length(); i > 0; i--)
56 myDocuments.Value(i)->SetUndoLimit(myUndoLimit);
60 //=======================================================================
63 //=======================================================================
65 void TDocStd_MultiTransactionManager::Undo()
67 if (myUndos.IsEmpty()) return;
68 const TDocStd_SequenceOfDocument& docs = myUndos.First()->GetDocuments();
70 for (i = docs.Length(); i > 0; i--) {
71 Handle(TDocStd_Document) doc = docs.Value(i);
72 if (doc.IsNull() || doc->GetAvailableUndos() == 0) continue;
75 myRedos.Prepend(myUndos.First());
77 myOpenTransaction = Standard_False;
80 //=======================================================================
83 //=======================================================================
85 void TDocStd_MultiTransactionManager::Redo() {
86 if (myRedos.IsEmpty()) return;
87 const TDocStd_SequenceOfDocument& docs = myRedos.First()->GetDocuments();
89 for (i = docs.Length(); i > 0; i--) {
90 Handle(TDocStd_Document) doc = docs.Value(i);
91 if (doc.IsNull() || doc->GetAvailableRedos() == 0) continue;
94 myUndos.Prepend(myRedos.First());
96 myOpenTransaction = Standard_False;
99 //=======================================================================
100 //function : OpenCommand
102 //=======================================================================
104 void TDocStd_MultiTransactionManager::OpenCommand() {
105 if (myOpenTransaction) {
107 std::cout << "TDocStd_MultiTransactionManager::OpenCommand(): "
108 "Can't start new application transaction while a "
109 "previous one is not commited or aborted" << std::endl;
111 throw Standard_Failure("Can't start new application transaction"
112 "while a previous one is not commited or aborted");
114 myOpenTransaction = Standard_True;
116 for(i = myDocuments.Length(); i > 0; i--) {
117 while(myDocuments.Value(i)->HasOpenCommand())
118 myDocuments.Value(i)->AbortCommand();
119 myDocuments.Value(i)->OpenCommand();
123 //=======================================================================
124 //function : AbortCommand
126 //=======================================================================
128 void TDocStd_MultiTransactionManager::AbortCommand() {
129 myOpenTransaction = Standard_False;
131 for(i = myDocuments.Length(); i > 0; i--) {
132 while(myDocuments.Value(i)->HasOpenCommand())
133 myDocuments.Value(i)->AbortCommand();
137 //=======================================================================
138 //function : CommitCommand
140 //=======================================================================
142 Standard_Boolean TDocStd_MultiTransactionManager::CommitCommand()
144 Handle(TDocStd_ApplicationDelta) aDelta = new TDocStd_ApplicationDelta;
145 Standard_Boolean isCommited = Standard_False;
147 for(i = myDocuments.Length(); i > 0; i--) {
148 isCommited = Standard_False;
149 while(myDocuments.Value(i)->HasOpenCommand())
150 if (myDocuments.Value(i)->CommitCommand())
151 isCommited = Standard_True;
153 aDelta->GetDocuments().Append(myDocuments.Value(i));
157 if (aDelta->GetDocuments().Length()) {
158 myUndos.Prepend(aDelta);
159 if (myUndos.Length() > myUndoLimit) {
163 isCommited = Standard_True;
165 myOpenTransaction = Standard_False;
169 //=======================================================================
170 //function : CommitCommand
172 //=======================================================================
174 Standard_Boolean TDocStd_MultiTransactionManager::CommitCommand
175 (const TCollection_ExtendedString& theName)
177 Standard_Boolean isCommited = CommitCommand();
178 if (isCommited && myUndos.Length())
179 myUndos.First()->SetName(theName);
183 //=======================================================================
184 //function : DumpTransaction
186 //=======================================================================
188 void TDocStd_MultiTransactionManager::DumpTransaction(Standard_OStream& anOS) const
191 if(myDocuments.Length() == 0)
192 anOS << "Manager is empty" << std::endl;
194 if(myDocuments.Length() == 1)
195 anOS << "There is one document ( ";
197 anOS << "There are " << myDocuments.Length() << " documents ( ";
198 for(i = 1; i <= myDocuments.Length(); i++) {
199 Handle(Standard_Transient) aDoc (myDocuments.Value(i));
200 anOS << "\"" << aDoc.get();
203 anOS << ") in the manager " << std::endl;
205 if(myIsNestedTransactionMode)
206 anOS << "Nested transaction mode is on" << std::endl;
208 anOS << "Nested transaction mode is off" << std::endl;
210 anOS << " " << std::endl;
213 for (i = myUndos.Length(); i > 0; i--) {
214 Handle(TDocStd_ApplicationDelta) delta = myUndos.Value(i);
218 anOS<<" < Last action"<<std::endl;
223 for (i = 1; i <= myRedos.Length(); i++) {
224 Handle(TDocStd_ApplicationDelta) delta = myRedos.Value(i);
231 //=======================================================================
232 //function : RemoveLastUndo
234 //=======================================================================
236 void TDocStd_MultiTransactionManager::RemoveLastUndo()
238 if(myUndos.Length() == 0) return;
239 const TDocStd_SequenceOfDocument& docs = myUndos.Last()->GetDocuments();
241 for (i = 1; i <= docs.Length(); i++) {
242 docs.Value(i)->RemoveFirstUndo();
244 myUndos.Remove(myUndos.Length());
247 //=======================================================================
248 //function : AddDocument
250 //=======================================================================
252 void TDocStd_MultiTransactionManager::AddDocument
253 (const Handle(TDocStd_Document)& theDoc)
256 for(i = myDocuments.Length(); i > 0; i--)
257 if(myDocuments.Value(i) == theDoc)
258 return; // the document is already added to the list
260 if(theDoc->IsNestedTransactionMode() !=
261 myIsNestedTransactionMode)
262 theDoc->SetNestedTransactionMode(myIsNestedTransactionMode);
264 theDoc->SetModificationMode(myOnlyTransactionModification);
266 myDocuments.Append(theDoc);
267 theDoc->SetUndoLimit(myUndoLimit);
268 if(myOpenTransaction) {
269 if(!theDoc->HasOpenCommand())
270 theDoc->OpenCommand();
273 if(theDoc->HasOpenCommand())
274 theDoc->CommitCommand();
276 theDoc->ClearUndos();
277 theDoc->ClearRedos();
280 //=======================================================================
281 //function : RemoveDocument
283 //=======================================================================
285 void TDocStd_MultiTransactionManager::RemoveDocument
286 (const Handle(TDocStd_Document)& theDoc)
289 for(i = myDocuments.Length(); i > 0; i--) {
290 if(myDocuments.Value(i) == theDoc)
291 myDocuments.Remove(i);
293 for (i = myUndos.Length(); i > 0; i--) {
294 Handle(TDocStd_ApplicationDelta) delta = myUndos.Value(i);
295 TDocStd_SequenceOfDocument& docs = delta->GetDocuments();
296 for(Standard_Integer j = docs.Length(); j > 0; j--) {
297 if(docs.Value(j) == theDoc) {
299 if(docs.Length() == 0)
304 for (i = myRedos.Length(); i > 0; i--) {
305 Handle(TDocStd_ApplicationDelta) delta = myRedos.Value(i);
306 TDocStd_SequenceOfDocument& docs = delta->GetDocuments();
307 for(Standard_Integer j = docs.Length(); j > 0; j--) {
308 if(docs.Value(j) == theDoc) {
310 if(docs.Length() == 0)
317 //=======================================================================
318 //function : SetNestedTransactionMode
320 //=======================================================================
322 void TDocStd_MultiTransactionManager::SetNestedTransactionMode
323 (const Standard_Boolean isAllowed)
325 myIsNestedTransactionMode = isAllowed;
327 for(i = myDocuments.Length(); i > 0; i--) {
328 if(myDocuments.Value(i)->IsNestedTransactionMode() != myIsNestedTransactionMode)
329 myDocuments.Value(i)->SetNestedTransactionMode(myIsNestedTransactionMode);
333 //=======================================================================
334 //function : SetModificationMode
335 //purpose : if theTransactionOnly is True changes is denied outside transactions
336 //=======================================================================
338 void TDocStd_MultiTransactionManager::SetModificationMode
339 (const Standard_Boolean theTransactionOnly)
341 myOnlyTransactionModification = theTransactionOnly;
344 for(i = myDocuments.Length(); i > 0; i--) {
345 myDocuments.Value(i)->SetModificationMode(myOnlyTransactionModification);
349 //=======================================================================
350 //function : ClearUndos
352 //=======================================================================
354 void TDocStd_MultiTransactionManager::ClearUndos()
360 for(i = myDocuments.Length(); i > 0; i--) {
361 myDocuments.Value(i)->ClearUndos();
365 //=======================================================================
366 //function : ClearRedos
368 //=======================================================================
370 void TDocStd_MultiTransactionManager::ClearRedos()
376 for(i = myDocuments.Length(); i > 0; i--) {
377 myDocuments.Value(i)->ClearRedos();