]> SALOME platform Git repositories - modules/gui.git/blob - src/CAF/CAF_Study.cxx
Salome HOME
Merge branch 'master' into abn/paravis_rearch
[modules/gui.git] / src / CAF / CAF_Study.cxx
1 // Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 #include "CAF_Study.h"
24
25 #include "CAF_Tools.h"
26 #include "CAF_Application.h"
27
28 #include <Basics_OCCTVersion.hxx>
29
30 #include <SUIT_Desktop.h>
31 #include <SUIT_MessageBox.h>
32 #include <SUIT_Application.h>
33
34 #include <QDir>
35
36 #include <TDF_Delta.hxx>
37 #include <TDF_ListIteratorOfDeltaList.hxx>
38 #include <TDocStd_Application.hxx>
39
40 #include <Standard_Failure.hxx>
41 #include <Standard_ErrorHandler.hxx>
42
43 /*!
44   \class CAF_Study
45   \brief Represents study for using in CAF module.
46
47   A study contains reference to OCAF std document and allows using OCAF services.
48   Provides necessary functionality for OCC transactions management.
49 */
50
51 /*!
52   \brief Constructor.
53   \param theApp application
54 */
55 CAF_Study::CAF_Study(SUIT_Application* theApp)
56 : SUIT_Study( theApp ),
57   myModifiedCnt( 0 )
58 {
59 }
60
61 /*!
62   \brief Constructor.
63   \param theApp application
64   \param aStdDoc OCAF document
65 */
66 CAF_Study::CAF_Study(SUIT_Application* theApp, Handle (TDocStd_Document)& aStdDoc)
67 : SUIT_Study( theApp ),
68   myStdDoc( aStdDoc ),
69   myModifiedCnt( 0 )
70 {
71 }
72
73 /*!
74   \brief Destructor.
75 */
76 CAF_Study::~CAF_Study()
77 {
78 }
79
80 /*!
81   \brief Get OCAF document.
82   \return handle to the OCAF document object
83 */
84 Handle(TDocStd_Document) CAF_Study::stdDoc() const
85 {
86   return myStdDoc;
87 }
88
89 /*!
90   \brief Set OCAF document.
91   \param aStdDoc new OCAF document
92 */
93 void CAF_Study::setStdDoc( Handle(TDocStd_Document)& aStdDoc )
94 {
95   myStdDoc = aStdDoc;
96 }
97
98 /*!
99   \brief Customize document initialization.
100   \param doc study name
101   \return \c true on success and \c false on error
102 */
103 bool CAF_Study::createDocument( const QString& doc )
104 {
105   bool res = SUIT_Study::createDocument( doc );
106
107   CAF_Application* app = cafApplication();
108   if ( res && app && !app->stdApp().IsNull() )
109   {
110     try {
111       OCC_CATCH_SIGNALS;
112       TColStd_SequenceOfExtendedString formats;
113       app->stdApp()->Formats( formats );
114       if ( !formats.IsEmpty() )
115         app->stdApp()->NewDocument( formats.First(), myStdDoc );
116     }
117     catch ( Standard_Failure ) {
118       res = false;
119     }
120   }
121   return res;
122 }
123
124 /*!
125   \brief Close document.
126   \param permanently if \c true, a document is closed permanently
127 */
128 void CAF_Study::closeDocument( bool permanently )
129 {
130   Handle(TDocStd_Application) app = stdApp();
131   if ( !app.IsNull() && !stdDoc().IsNull() )
132     app->Close( stdDoc() );
133
134   SUIT_Study::closeDocument( permanently );
135 }
136
137 /*!
138   \brief Open document.
139   \param fname study file name
140   \return \c true on success and \c false if document cannot be opened
141 */
142 bool CAF_Study::openDocument( const QString& fname )
143 {
144   Handle(TDocStd_Application) app = stdApp();
145   if ( app.IsNull() )
146     return false;
147
148   bool status = false;
149   try {
150     OCC_CATCH_SIGNALS;
151     status = app->Open( CAF_Tools::toExtString( fname ), myStdDoc ) == PCDM_RS_OK;
152   }
153   catch ( Standard_Failure ) {
154     status = false;
155   }
156
157   return status && SUIT_Study::openDocument( fname );
158 }
159
160 /*!
161   \brief Save document with other name.
162   \param fname study file name
163 */
164 bool CAF_Study::saveDocumentAs( const QString& fname )
165 {
166   Handle(TDocStd_Application) app = stdApp();
167   if ( app.IsNull() )
168     return false;
169
170   bool save = false;
171   if ( !stdDoc().IsNull() && stdDoc()->IsSaved() )
172   {
173     QString path = QDir::convertSeparators( CAF_Tools::toQString( stdDoc()->GetPath() ) );
174     save = path == QDir::convertSeparators( fname );
175   }
176
177   bool status = false;
178   try {
179     OCC_CATCH_SIGNALS;
180     if ( save )
181       status = app->Save( stdDoc() ) == PCDM_SS_OK;
182     else
183     {
184       TCollection_ExtendedString format, path( CAF_Tools::toExtString( fname ) );
185       app->Format( path, format );
186
187       if ( format.Length() )
188         stdDoc()->ChangeStorageFormat( format );
189
190       status = app->SaveAs( stdDoc(), path ) == PCDM_SS_OK;
191     }
192   }
193   catch ( Standard_Failure ) {
194     status = false;
195   }
196
197   if ( status )
198     status = SUIT_Study::saveDocumentAs( fname );
199
200   if ( status )
201     myModifiedCnt = 0;
202
203   return status;
204 }
205
206 /*!
207   \brief Open OCAF transaction.
208   \return \c true if transaction is opened successfully
209 */
210 bool CAF_Study::openTransaction()
211 {
212   if ( myStdDoc.IsNull() )
213     return false;
214
215   bool res = true;
216   try {
217     OCC_CATCH_SIGNALS;
218     if ( myStdDoc->HasOpenCommand() )
219       myStdDoc->AbortCommand();
220
221     myStdDoc->OpenCommand();
222   }
223   catch ( Standard_Failure ) {
224     res = false;
225   }
226
227   return res;
228 }
229
230 /*!
231   \brief Abort OCAF transaction.
232   \return \c true if transaction is aborted successfully
233 */
234 bool CAF_Study::abortTransaction()
235 {
236   if ( myStdDoc.IsNull() )
237     return false;
238
239   bool res = true;
240   try {
241     OCC_CATCH_SIGNALS;
242     myStdDoc->AbortCommand();
243     update();
244   }
245   catch ( Standard_Failure ) {
246     res = false;
247   }
248   return res;
249 }
250
251 /*!
252   \brief Commit OCAF transaction
253   \return \c true if transaction is committed successfully
254 */
255 bool CAF_Study::commitTransaction( const QString& name )
256 {
257   if ( myStdDoc.IsNull() )
258     return false;
259
260   bool res = true;
261   try {
262     OCC_CATCH_SIGNALS;
263     myStdDoc->CommitCommand();
264
265     if ( canUndo() )
266     {
267       Handle(TDF_Delta) d = myStdDoc->GetUndos().Last();
268       if ( !d.IsNull() )
269         d->SetName( CAF_Tools::toExtString( name ) );
270     }
271   }
272   catch ( Standard_Failure ) {
273     res = false;
274   }
275   return res;
276 }
277
278 /*!
279   \brief Check if there is any transaction opened.
280   \return \c true if there is opened OCAF transaction
281 */
282 bool CAF_Study::hasTransaction() const
283 {
284   if ( myStdDoc.IsNull() )
285     return false;
286
287   return myStdDoc->HasOpenCommand();
288 }
289
290 /*!
291   \brief Check if the study is saved.
292   \return \c true if the document has been saved to file
293 */
294 bool CAF_Study::isSaved() const
295 {
296   if ( myStdDoc.IsNull() )
297     return false;
298
299   return myStdDoc->IsSaved();
300 }
301
302 /*!
303   \brief Check if the study is modified.
304   \return \c true if the document has been modified
305 */
306 bool CAF_Study::isModified() const
307 {
308   if ( myStdDoc.IsNull() )
309     return false;
310
311 //  return myStdDoc->IsModified();
312   return myModifiedCnt;
313 }
314
315 /*!
316   \brief Increment modifications count.
317
318   If \a undoable is \c true, this modification can be rolled back by
319   undoModified(), otherwise the document will be marked as \c modified
320   until it is saved.
321
322   \param undoable if \c true the operation is undoable
323   \sa undoModified(), clearModified()
324 */
325 void CAF_Study::doModified( bool undoable )
326 {
327   if ( myStdDoc.IsNull() )
328     return;
329
330   myModifiedCnt++;
331
332   /*  Assumed that number of available undos / redos is NOT changed dynamically */
333   if ( !undoable )
334     myModifiedCnt += myStdDoc->GetAvailableUndos();
335 }
336
337 /*!
338   \brief Decrement modifications count.
339   \sa doModified(), clearModified()
340 */
341 void CAF_Study::undoModified()
342 {
343   myModifiedCnt--;
344 }
345
346 /*!
347   \brief Clear modifications count.
348   \sa doModified(), undoModified()
349 */
350 void CAF_Study::clearModified()
351 {
352   myModifiedCnt = 0;
353 }
354
355 /*!
356   \brief Undo the last command.
357   \return \c true on success and \c false on error
358 */
359 bool CAF_Study::undo()
360 {
361   if ( myStdDoc.IsNull() )
362     return false;
363
364   try {
365     OCC_CATCH_SIGNALS;
366     myStdDoc->Undo();
367     undoModified();     /* decrement modification counter */
368   }
369   catch ( Standard_Failure ) {
370     SUIT_MessageBox::critical(application()->desktop(), tr( "ERR_ERROR" ),
371                               tr( "ERR_DOC_UNDO" ));
372     return false;
373   }
374   return true;
375 }
376
377 /*!
378   \brief Redo the last undo.
379   \return \c true on success and \c false on error
380 */
381 bool CAF_Study::redo()
382 {
383   if ( myStdDoc.IsNull() )
384     return false;
385
386   try {
387     OCC_CATCH_SIGNALS;
388     myStdDoc->Redo();
389     doModified();      /* increment modification counter */
390   }
391   catch ( Standard_Failure ) {
392     SUIT_MessageBox::critical( application()->desktop(), tr( "ERR_ERROR" ),
393                                tr( "ERR_DOC_REDO" ) );
394     return false;
395   }
396   return true;
397 }
398
399 /*!
400   \brief Check if it is possible to undo last command.
401   \return \c true if undo is avaiable
402 */
403 bool CAF_Study::canUndo() const
404 {
405   if ( myStdDoc.IsNull() )
406     return false;
407
408   return myStdDoc->GetAvailableUndos() > 0;
409 }
410
411 /*!
412   \brief Check if it is possible to redo last undo.
413   \return \c true if redo is avaiable
414 */
415 bool CAF_Study::canRedo() const
416 {
417   if ( myStdDoc.IsNull() )
418     return false;
419
420   return myStdDoc->GetAvailableRedos() > 0;
421 }
422
423 /*!
424   \brief Get names of available undo commands.
425   \return list of commands names
426 */
427 QStringList CAF_Study::undoNames() const
428 {
429   QStringList names;
430   if ( !myStdDoc.IsNull() )
431   {
432     for ( TDF_ListIteratorOfDeltaList it( myStdDoc->GetUndos() ); it.More(); it.Next() )
433       names.prepend( CAF_Tools::toQString( it.Value()->Name() ) );
434   }
435   return names;
436 }
437
438 /*!
439   \brief Get names of available redo commands.
440   \return list of commands names
441 */
442 QStringList CAF_Study::redoNames() const
443 {
444   QStringList names;
445   if ( !myStdDoc.IsNull() )
446   {
447     for ( TDF_ListIteratorOfDeltaList it( myStdDoc->GetRedos() ); it.More(); it.Next() )
448       names.append( CAF_Tools::toQString( it.Value()->Name() ) );
449   }
450   return names;
451 }
452
453 /*!
454   \brief Get OCAF application.
455   \return handle to the OCAF application object
456 */
457 Handle(TDocStd_Application) CAF_Study::stdApp() const
458 {
459   Handle(TDocStd_Application) stdApp;
460   CAF_Application* app = cafApplication();
461   if ( app )
462     stdApp = app->stdApp();
463   return stdApp;
464 }
465
466 /*!
467   \brief Get application.
468   \return application object (CAF_Application)
469 */
470 CAF_Application* CAF_Study::cafApplication() const
471 {
472   return qobject_cast<CAF_Application*>( application() );
473 }