Salome HOME
176023a1f03492b444a7d914c05e37295eb90384
[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   if ( status )
144     status = SUIT_Study::saveDocumentAs( fname );
145
146   if ( status )
147     myModifiedCnt = 0;
148
149   return status;
150 }
151
152 bool CAF_Study::openTransaction()
153 {
154         if ( myStdDoc.IsNull() )
155     return false;
156
157   bool res = true;
158   try {
159     if ( myStdDoc->HasOpenCommand() )
160       myStdDoc->AbortCommand();
161
162     myStdDoc->OpenCommand();
163   }
164   catch ( Standard_Failure ) {
165     res = false;
166   }
167
168   return res;
169 }
170
171 bool CAF_Study::abortTransaction()
172 {
173         if ( myStdDoc.IsNull() )
174     return false;
175
176   bool res = true;
177         try {
178     myStdDoc->AbortCommand();
179                 update();
180   }
181   catch ( Standard_Failure ) {
182     res = false;
183   }
184   return res;
185 }
186
187 bool CAF_Study::commitTransaction( const QString& name )
188 {
189         if ( myStdDoc.IsNull() )
190     return false;
191
192   bool res = true;
193         try {
194     myStdDoc->CommitCommand();
195
196     if ( canUndo() )
197     {
198       Handle(TDF_Delta) d = myStdDoc->GetUndos().Last();
199                         if ( !d.IsNull() )
200         d->SetName( CAF_Tools::toExtString( name ) );
201     }
202   }
203   catch ( Standard_Failure ) {
204     res = false;
205   }
206   return res;
207 }
208
209 bool CAF_Study::hasTransaction() const
210 {
211         if ( myStdDoc.IsNull() )
212     return false;
213
214   return myStdDoc->HasOpenCommand();
215 }
216
217 /*!
218     Returns whether the document was saved in file. [ public ]
219 */
220 bool CAF_Study::isSaved() const
221 {
222         if ( myStdDoc.IsNull() )
223     return false;
224
225   return myStdDoc->IsSaved();
226 }
227
228 /*!
229     Returns whether the document is modified. [ public ]
230 */
231 bool CAF_Study::isModified() const
232 {
233         if ( myStdDoc.IsNull() )
234     return false;
235
236 //  return myStdDoc->IsModified();
237   return myModifiedCnt;
238 }
239
240 /*!
241     Increments modification count. If 'undoable' is 'true', this modification
242     can be rolled back by 'undoModified' otherwise the document will be marked
243     as 'modiifed' until saved. [ protected ]
244 */
245 void CAF_Study::doModified( bool undoable )
246 {
247         if ( myStdDoc.IsNull() )
248     return;
249
250         myModifiedCnt++;
251
252     /*  Assumed that number of available undos / redos is NOT changed dynamically */
253         if ( !undoable )
254     myModifiedCnt += myStdDoc->GetAvailableUndos();
255 }
256
257 /*!
258     Decrements modification count. [ protected ]
259 */
260 void CAF_Study::undoModified()
261 {
262   myModifiedCnt--;
263 }
264
265 /*!
266     Clears modification count. [ public ]
267 */
268 void CAF_Study::clearModified()
269 {
270   myModifiedCnt = 0;
271 }
272
273 /*!
274     Undoes the last command. [ public ]
275 */
276 bool CAF_Study::undo()
277 {
278         if ( myStdDoc.IsNull() )
279     return false;
280
281   try {
282     myStdDoc->Undo();
283     undoModified();     /* decrement modification counter */
284   }
285   catch ( Standard_Failure ) {
286                 SUIT_MessageBox::error1( application()->desktop(), tr( "ERR_ERROR" ),
287                              tr( "ERR_DOC_UNDO" ), tr ( "BUT_OK" ) );
288                 return false;
289         }
290   return true;
291 }
292
293 /*!
294     Redoes the last undo. [ public ]
295 */
296 bool CAF_Study::redo()
297 {
298         if ( myStdDoc.IsNull() )
299     return false;
300
301   try {
302     myStdDoc->Redo();
303     doModified();      /* increment modification counter */
304   }
305   catch ( Standard_Failure ) {
306     SUIT_MessageBox::error1( application()->desktop(), tr( "ERR_ERROR" ),
307                              tr( "ERR_DOC_REDO" ), tr ( "BUT_OK" ) );
308     return false;
309   }
310   return true;
311 }
312
313 /*!
314     Check if possible to perform 'undo' command. [ public ]
315 */
316 bool CAF_Study::canUndo() const
317 {
318   if ( myStdDoc.IsNull() )
319     return false;
320
321   return myStdDoc->GetAvailableUndos() > 0;
322 }
323
324 /*!
325     Check if possible to perform 'redo' command. [ public ]
326 */
327 bool CAF_Study::canRedo() const
328 {
329   if ( myStdDoc.IsNull() )
330     return false;
331
332   return myStdDoc->GetAvailableRedos() > 0;
333 }
334
335 /*!
336     Returns the list of names of 'undo' actions available. [ public ]
337 */
338 QStringList CAF_Study::undoNames() const
339 {
340   QStringList names;
341   if ( !myStdDoc.IsNull() )
342   {
343     for ( TDF_ListIteratorOfDeltaList it( myStdDoc->GetUndos() ); it.More(); it.Next() )
344       names.prepend( CAF_Tools::toQString( it.Value()->Name() ) );
345   }
346   return names;
347 }
348
349 /*!
350     Returns the list of names of 'redo' actions available. [ public ]
351 */
352 QStringList CAF_Study::redoNames() const
353 {
354   QStringList names;
355   if ( !myStdDoc.IsNull() )
356   {
357     for ( TDF_ListIteratorOfDeltaList it( myStdDoc->GetRedos() ); it.More(); it.Next() )
358       names.append( CAF_Tools::toQString( it.Value()->Name() ) );
359   }
360   return names;
361 }
362
363 /*!
364     Returns the standard OCAF application from owner application. [ protected ]
365 */
366 Handle(TDocStd_Application) CAF_Study::stdApp() const
367 {
368   Handle(TDocStd_Application) stdApp;
369   CAF_Application* app = cafApplication();
370   if ( app )
371     stdApp = app->stdApp();
372   return stdApp;
373 }
374
375 /*!
376     Returns the application casted to type CAF_Application. [ protected ]
377 */
378 CAF_Application* CAF_Study::cafApplication() const
379 {
380   return ::qt_cast<CAF_Application*>( application() );
381 }