Salome HOME
Copyrights update
[modules/gui.git] / src / CAF / CAF_Study.cxx
1 // Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
2 // 
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either 
6 // version 2.1 of the License.
7 // 
8 // This library is distributed in the hope that it will be useful 
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public  
14 // License along with this library; if not, write to the Free Software 
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/
18 //
19 #include "CAF_Study.h"
20
21 #include "CAF_Tools.h"
22 #include "CAF_Operation.h"
23 #include "CAF_Application.h"
24
25 #include <SUIT_Desktop.h>
26 #include <SUIT_MessageBox.h>
27 #include <SUIT_Application.h>
28
29 #include <qdir.h>
30
31 #include <TDF_Delta.hxx>
32 #include <TDF_ListIteratorOfDeltaList.hxx>
33
34 #include <Standard_ErrorHandler.hxx>
35
36 //////////////////////////////////////////////////////////////////////
37 // Construction/Destruction
38 //////////////////////////////////////////////////////////////////////
39
40 CAF_Study::CAF_Study(SUIT_Application* theApp)
41 : SUIT_Study( theApp ),
42 myModifiedCnt( 0 )
43 {
44 }
45
46 CAF_Study::CAF_Study(SUIT_Application* theApp, Handle (TDocStd_Document)& aStdDoc)
47 : SUIT_Study( theApp ),
48 myStdDoc( aStdDoc ),
49 myModifiedCnt( 0 )
50 {
51 }
52
53 CAF_Study::~CAF_Study()
54 {
55 }
56
57 Handle(TDocStd_Document) CAF_Study::stdDoc() const
58 {
59   return myStdDoc;
60 }
61
62 void CAF_Study::setStdDoc( Handle(TDocStd_Document)& aStdDoc )
63 {
64   myStdDoc = aStdDoc;
65 }
66
67 void CAF_Study::createDocument()
68 {
69   SUIT_Study::createDocument();
70
71   CAF_Application* app = cafApplication();
72   if ( app && !app->stdApp().IsNull() )
73   {
74     try {
75       TColStd_SequenceOfExtendedString formats;
76             app->stdApp()->Formats( formats );
77       if ( !formats.IsEmpty() )
78         app->stdApp()->NewDocument( formats.First(), myStdDoc );
79     }
80     catch ( Standard_Failure ) {
81     }
82   }
83 }
84
85 void CAF_Study::closeDocument( bool permanent )
86 {
87   Handle(TDocStd_Application) app = stdApp();
88   if ( !app.IsNull() && !stdDoc().IsNull() )
89     app->Close( stdDoc() );
90
91   SUIT_Study::closeDocument( permanent );
92 }
93
94 bool CAF_Study::openDocument( const QString& fname )
95 {
96   Handle(TDocStd_Application) app = stdApp();
97   if ( app.IsNull() )
98     return false;
99
100   bool status = false;
101   try {
102     status = app->Open( CAF_Tools::toExtString( fname ), myStdDoc ) == CDF_RS_OK;
103   }
104   catch ( Standard_Failure ) {
105     status = false;
106   }
107
108   return status && SUIT_Study::openDocument( fname );
109 }
110
111 bool CAF_Study::saveDocumentAs( const QString& fname )
112 {
113   Handle(TDocStd_Application) app = stdApp();
114   if ( app.IsNull() )
115     return false;
116
117   bool save = false;
118   if ( !stdDoc().IsNull() && stdDoc()->IsSaved() )
119   {
120     QString path = QDir::convertSeparators( CAF_Tools::toQString( stdDoc()->GetPath() ) );
121     save = path == QDir::convertSeparators( fname );
122   }
123
124   bool status = false;
125   try {
126     if ( save )
127       status = app->Save( stdDoc() ) == CDF_SS_OK;
128     else
129     {
130       TCollection_ExtendedString format, path( CAF_Tools::toExtString( fname ) );
131       app->Format( path, format );
132
133       if ( format.Length() )
134         stdDoc()->ChangeStorageFormat( format );
135
136       status = app->SaveAs( stdDoc(), path ) == CDF_SS_OK;
137     }
138   }
139   catch ( Standard_Failure ) {
140     status = false;
141   }
142
143   return status && SUIT_Study::saveDocumentAs( fname );
144 }
145
146 bool CAF_Study::openTransaction()
147 {
148         if ( myStdDoc.IsNull() )
149     return false;
150
151   bool res = true;
152   try {
153     if ( myStdDoc->HasOpenCommand() )
154       myStdDoc->AbortCommand();
155
156     myStdDoc->OpenCommand();
157   }
158   catch ( Standard_Failure ) {
159     res = false;
160   }
161
162   return res;
163 }
164
165 bool CAF_Study::abortTransaction()
166 {
167         if ( myStdDoc.IsNull() )
168     return false;
169
170   bool res = true;
171         try {
172     myStdDoc->AbortCommand();
173                 update();
174   }
175   catch ( Standard_Failure ) {
176     res = false;
177   }
178   return res;
179 }
180
181 bool CAF_Study::commitTransaction( const QString& name )
182 {
183         if ( myStdDoc.IsNull() )
184     return false;
185
186   bool res = true;
187         try {
188     myStdDoc->CommitCommand();
189
190     if ( canUndo() )
191     {
192       Handle(TDF_Delta) d = myStdDoc->GetUndos().Last();
193                         if ( !d.IsNull() )
194         d->SetName( CAF_Tools::toExtString( name ) );
195     }
196   }
197   catch ( Standard_Failure ) {
198     res = false;
199   }
200   return res;
201 }
202
203 bool CAF_Study::hasTransaction() const
204 {
205         if ( myStdDoc.IsNull() )
206     return false;
207
208   return myStdDoc->HasOpenCommand();
209 }
210
211 /*!
212     Returns whether the document was saved in file. [ public ]
213 */
214 bool CAF_Study::isSaved() const
215 {
216         if ( myStdDoc.IsNull() )
217     return false;
218
219   return myStdDoc->IsSaved();
220 }
221
222 /*!
223     Returns whether the document is modified. [ public ]
224 */
225 bool CAF_Study::isModified() const
226 {
227   return ( myModifiedCnt != 0 );
228 }
229
230 /*!
231     Increments modification count. If 'undoable' is 'true', this modification
232     can be rolled back by 'undoModified' otherwise the document will be marked
233     as 'modiifed' until saved. [ protected ]
234 */
235 void CAF_Study::doModified( bool undoable )
236 {
237         if ( myStdDoc.IsNull() )
238     return;
239
240         myModifiedCnt++;
241
242     /*  Assumed that number of available undos / redos is NOT changed dynamically */
243         if ( !undoable )
244     myModifiedCnt += myStdDoc->GetAvailableUndos();
245 }
246
247 /*!
248     Decrements modification count. [ protected ]
249 */
250 void CAF_Study::undoModified()
251 {
252   myModifiedCnt--;
253 }
254
255 /*!
256     Clears modification count. [ public ]
257 */
258 void CAF_Study::clearModified()
259 {
260   myModifiedCnt = 0;
261 }
262
263 /*!
264     Undoes the last command. [ public ]
265 */
266 bool CAF_Study::undo()
267 {
268         if ( myStdDoc.IsNull() )
269     return false;
270
271   try {
272     myStdDoc->Undo();
273     undoModified();     /* decrement modification counter */
274   }
275   catch ( Standard_Failure ) {
276                 SUIT_MessageBox::error1( application()->desktop(), tr( "ERR_ERROR" ),
277                              tr( "ERR_DOC_UNDO" ), tr ( "BUT_OK" ) );
278                 return false;
279         }
280   return true;
281 }
282
283 /*!
284     Redoes the last undo. [ public ]
285 */
286 bool CAF_Study::redo()
287 {
288         if ( myStdDoc.IsNull() )
289     return false;
290
291   try {
292     myStdDoc->Redo();
293     doModified();      /* increment modification counter */
294   }
295   catch ( Standard_Failure ) {
296     SUIT_MessageBox::error1( application()->desktop(), tr( "ERR_ERROR" ),
297                              tr( "ERR_DOC_REDO" ), tr ( "BUT_OK" ) );
298     return false;
299   }
300   return true;
301 }
302
303 /*!
304     Check if possible to perform 'undo' command. [ public ]
305 */
306 bool CAF_Study::canUndo() const
307 {
308   if ( myStdDoc.IsNull() )
309     return false;
310
311   return myStdDoc->GetAvailableUndos() > 0;
312 }
313
314 /*!
315     Check if possible to perform 'redo' command. [ public ]
316 */
317 bool CAF_Study::canRedo() const
318 {
319   if ( myStdDoc.IsNull() )
320     return false;
321
322   return myStdDoc->GetAvailableRedos() > 0;
323 }
324
325 /*!
326     Returns the list of names of 'undo' actions available. [ public ]
327 */
328 QStringList CAF_Study::undoNames() const
329 {
330   QStringList names;
331   if ( !myStdDoc.IsNull() )
332   {
333     for ( TDF_ListIteratorOfDeltaList it( myStdDoc->GetUndos() ); it.More(); it.Next() )
334       names.prepend( CAF_Tools::toQString( it.Value()->Name() ) );
335   }
336   return names;
337 }
338
339 /*!
340     Returns the list of names of 'redo' actions available. [ public ]
341 */
342 QStringList CAF_Study::redoNames() const
343 {
344   QStringList names;
345   if ( !myStdDoc.IsNull() )
346   {
347     for ( TDF_ListIteratorOfDeltaList it( myStdDoc->GetRedos() ); it.More(); it.Next() )
348       names.append( CAF_Tools::toQString( it.Value()->Name() ) );
349   }
350   return names;
351 }
352
353 /*!
354     Returns the standard OCAF application from owner application. [ protected ]
355 */
356 Handle(TDocStd_Application) CAF_Study::stdApp() const
357 {
358   Handle(TDocStd_Application) stdApp;
359   CAF_Application* app = cafApplication();
360   if ( app )
361     stdApp = app->stdApp();
362   return stdApp;
363 }
364
365 /*!
366     Returns the application casted to type CAF_Application. [ protected ]
367 */
368 CAF_Application* CAF_Study::cafApplication() const
369 {
370   return ::qt_cast<CAF_Application*>( application() );
371 }