Salome HOME
30362443daa6d9b950957f0764ae5d4ff82419ef
[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   Constructor
38 */
39 CAF_Study::CAF_Study(SUIT_Application* theApp)
40 : SUIT_Study( theApp ),
41 myModifiedCnt( 0 )
42 {
43 }
44
45 /*!
46   Constructor
47 */
48 CAF_Study::CAF_Study(SUIT_Application* theApp, Handle (TDocStd_Document)& aStdDoc)
49 : SUIT_Study( theApp ),
50 myStdDoc( aStdDoc ),
51 myModifiedCnt( 0 )
52 {
53 }
54
55 /*!
56   Destructor
57 */
58 CAF_Study::~CAF_Study()
59 {
60 }
61
62 /*!
63   \return OCAF document
64 */
65 Handle(TDocStd_Document) CAF_Study::stdDoc() const
66 {
67   return myStdDoc;
68 }
69
70 /*!
71   Sets new OCAF document
72   \param aStdDoc - new OCAF document
73 */
74 void CAF_Study::setStdDoc( Handle(TDocStd_Document)& aStdDoc )
75 {
76   myStdDoc = aStdDoc;
77 }
78
79 /*!
80   Custom document initialization
81 */
82 void CAF_Study::createDocument()
83 {
84   SUIT_Study::createDocument();
85
86   CAF_Application* app = cafApplication();
87   if ( app && !app->stdApp().IsNull() )
88   {
89     try {
90       TColStd_SequenceOfExtendedString formats;
91             app->stdApp()->Formats( formats );
92       if ( !formats.IsEmpty() )
93         app->stdApp()->NewDocument( formats.First(), myStdDoc );
94     }
95     catch ( Standard_Failure ) {
96     }
97   }
98 }
99
100 /*!
101   Close document
102 */
103 void CAF_Study::closeDocument( bool permanent )
104 {
105   Handle(TDocStd_Application) app = stdApp();
106   if ( !app.IsNull() && !stdDoc().IsNull() )
107     app->Close( stdDoc() );
108
109   SUIT_Study::closeDocument( permanent );
110 }
111
112 /*!
113   Open document
114   \param fname - name of file
115 */
116 bool CAF_Study::openDocument( const QString& fname )
117 {
118   Handle(TDocStd_Application) app = stdApp();
119   if ( app.IsNull() )
120     return false;
121
122   bool status = false;
123   try {
124     status = app->Open( CAF_Tools::toExtString( fname ), myStdDoc ) == CDF_RS_OK;
125   }
126   catch ( Standard_Failure ) {
127     status = false;
128   }
129
130   return status && SUIT_Study::openDocument( fname );
131 }
132
133 /*!
134   Save document with other name
135   \param fname - name of file
136 */
137 bool CAF_Study::saveDocumentAs( const QString& fname )
138 {
139   Handle(TDocStd_Application) app = stdApp();
140   if ( app.IsNull() )
141     return false;
142
143   bool save = false;
144   if ( !stdDoc().IsNull() && stdDoc()->IsSaved() )
145   {
146     QString path = QDir::convertSeparators( CAF_Tools::toQString( stdDoc()->GetPath() ) );
147     save = path == QDir::convertSeparators( fname );
148   }
149
150   bool status = false;
151   try {
152     if ( save )
153       status = app->Save( stdDoc() ) == CDF_SS_OK;
154     else
155     {
156       TCollection_ExtendedString format, path( CAF_Tools::toExtString( fname ) );
157       app->Format( path, format );
158
159       if ( format.Length() )
160         stdDoc()->ChangeStorageFormat( format );
161
162       status = app->SaveAs( stdDoc(), path ) == CDF_SS_OK;
163     }
164   }
165   catch ( Standard_Failure ) {
166     status = false;
167   }
168
169   if ( status )
170     status = SUIT_Study::saveDocumentAs( fname );
171
172   if ( status )
173     myModifiedCnt = 0;
174
175   return status;
176 }
177
178 /*!
179   Open OCAF transaction
180 */
181 bool CAF_Study::openTransaction()
182 {
183   if ( myStdDoc.IsNull() )
184     return false;
185
186   bool res = true;
187   try {
188     if ( myStdDoc->HasOpenCommand() )
189       myStdDoc->AbortCommand();
190
191     myStdDoc->OpenCommand();
192   }
193   catch ( Standard_Failure ) {
194     res = false;
195   }
196
197   return res;
198 }
199
200 /*!
201   Abort OCAF transaction
202 */
203 bool CAF_Study::abortTransaction()
204 {
205   if ( myStdDoc.IsNull() )
206     return false;
207
208   bool res = true;
209   try {
210     myStdDoc->AbortCommand();
211                 update();
212   }
213   catch ( Standard_Failure ) {
214     res = false;
215   }
216   return res;
217 }
218
219 /*!
220   Commit OCAF transaction
221 */
222 bool CAF_Study::commitTransaction( const QString& name )
223 {
224   if ( myStdDoc.IsNull() )
225     return false;
226
227   bool res = true;
228   try {
229     myStdDoc->CommitCommand();
230
231     if ( canUndo() )
232     {
233       Handle(TDF_Delta) d = myStdDoc->GetUndos().Last();
234                         if ( !d.IsNull() )
235         d->SetName( CAF_Tools::toExtString( name ) );
236     }
237   }
238   catch ( Standard_Failure ) {
239     res = false;
240   }
241   return res;
242 }
243
244 /*!
245   \return true, if there is opened OCAF transaction
246 */
247 bool CAF_Study::hasTransaction() const
248 {
249   if ( myStdDoc.IsNull() )
250     return false;
251
252   return myStdDoc->HasOpenCommand();
253 }
254
255 /*!
256   \return whether the document was saved in file. [ public ]
257 */
258 bool CAF_Study::isSaved() const
259 {
260   if ( myStdDoc.IsNull() )
261     return false;
262
263   return myStdDoc->IsSaved();
264 }
265
266 /*!
267   \return whether the document is modified. [ public ]
268 */
269 bool CAF_Study::isModified() const
270 {
271   if ( myStdDoc.IsNull() )
272     return false;
273
274 //  return myStdDoc->IsModified();
275   return myModifiedCnt;
276 }
277
278 /*!
279     Increments modification count. If 'undoable' is 'true', this modification
280     can be rolled back by 'undoModified' otherwise the document will be marked
281     as 'modiifed' until saved. [ protected ]
282 */
283 void CAF_Study::doModified( bool undoable )
284 {
285         if ( myStdDoc.IsNull() )
286     return;
287
288         myModifiedCnt++;
289
290     /*  Assumed that number of available undos / redos is NOT changed dynamically */
291         if ( !undoable )
292     myModifiedCnt += myStdDoc->GetAvailableUndos();
293 }
294
295 /*!
296     Decrements modification count. [ protected ]
297 */
298 void CAF_Study::undoModified()
299 {
300   myModifiedCnt--;
301 }
302
303 /*!
304     Clears modification count. [ public ]
305 */
306 void CAF_Study::clearModified()
307 {
308   myModifiedCnt = 0;
309 }
310
311 /*!
312     Undoes the last command. [ public ]
313 */
314 bool CAF_Study::undo()
315 {
316         if ( myStdDoc.IsNull() )
317     return false;
318
319   try {
320     myStdDoc->Undo();
321     undoModified();     /* decrement modification counter */
322   }
323   catch ( Standard_Failure ) {
324                 SUIT_MessageBox::error1( application()->desktop(), tr( "ERR_ERROR" ),
325                              tr( "ERR_DOC_UNDO" ), tr ( "BUT_OK" ) );
326                 return false;
327         }
328   return true;
329 }
330
331 /*!
332     Redoes the last undo. [ public ]
333 */
334 bool CAF_Study::redo()
335 {
336         if ( myStdDoc.IsNull() )
337     return false;
338
339   try {
340     myStdDoc->Redo();
341     doModified();      /* increment modification counter */
342   }
343   catch ( Standard_Failure ) {
344     SUIT_MessageBox::error1( application()->desktop(), tr( "ERR_ERROR" ),
345                              tr( "ERR_DOC_REDO" ), tr ( "BUT_OK" ) );
346     return false;
347   }
348   return true;
349 }
350
351 /*!
352   \return true if possible to perform 'undo' command. [ public ]
353 */
354 bool CAF_Study::canUndo() const
355 {
356   if ( myStdDoc.IsNull() )
357     return false;
358
359   return myStdDoc->GetAvailableUndos() > 0;
360 }
361
362 /*!
363   \return true if possible to perform 'redo' command. [ public ]
364 */
365 bool CAF_Study::canRedo() const
366 {
367   if ( myStdDoc.IsNull() )
368     return false;
369
370   return myStdDoc->GetAvailableRedos() > 0;
371 }
372
373 /*!
374   \return the list of names of 'undo' actions available. [ public ]
375 */
376 QStringList CAF_Study::undoNames() const
377 {
378   QStringList names;
379   if ( !myStdDoc.IsNull() )
380   {
381     for ( TDF_ListIteratorOfDeltaList it( myStdDoc->GetUndos() ); it.More(); it.Next() )
382       names.prepend( CAF_Tools::toQString( it.Value()->Name() ) );
383   }
384   return names;
385 }
386
387 /*!
388   \return the list of names of 'redo' actions available. [ public ]
389 */
390 QStringList CAF_Study::redoNames() const
391 {
392   QStringList names;
393   if ( !myStdDoc.IsNull() )
394   {
395     for ( TDF_ListIteratorOfDeltaList it( myStdDoc->GetRedos() ); it.More(); it.Next() )
396       names.append( CAF_Tools::toQString( it.Value()->Name() ) );
397   }
398   return names;
399 }
400
401 /*!
402   \return the standard OCAF application from owner application. [ protected ]
403 */
404 Handle(TDocStd_Application) CAF_Study::stdApp() const
405 {
406   Handle(TDocStd_Application) stdApp;
407   CAF_Application* app = cafApplication();
408   if ( app )
409     stdApp = app->stdApp();
410   return stdApp;
411 }
412
413 /*!
414   \return the application casted to type CAF_Application. [ protected ]
415 */
416 CAF_Application* CAF_Study::cafApplication() const
417 {
418   return ::qt_cast<CAF_Application*>( application() );
419 }