Salome HOME
Fix a bug of SALOME_PYQT package - to work properly with Sip and PyQt libraries addit...
[modules/gui.git] / src / SalomeApp / SalomeApp_Study.cxx
1 #include "SalomeApp_Study.h"
2
3 #include "SalomeApp_Module.h"
4 #include "SalomeApp_DataModel.h"
5 #include "SalomeApp_RootObject.h"
6 #include "SalomeApp_DataObject.h"
7 #include "SalomeApp_Application.h"
8
9 #include <OB_Browser.h>
10
11 #include <SUIT_ResourceMgr.h>
12
13 #include "utilities.h"
14
15 /*!
16   Constructor.
17 */
18 SalomeApp_Study::SalomeApp_Study( SUIT_Application* app )
19 : CAM_Study( app )
20 {
21 }  
22
23 /*!
24   Destructor.
25 */
26 SalomeApp_Study::~SalomeApp_Study()
27 {
28 }
29
30 /*!
31   Gets study id.
32 */
33 int SalomeApp_Study::id() const
34 {
35   int id = -1;
36   if ( myStudyDS )
37     id = studyDS()->StudyId();
38   return id;
39 }
40
41 /*!
42   Gets studyDS pointer.
43 */
44 _PTR(Study) SalomeApp_Study::studyDS() const
45 {
46   return myStudyDS;
47 }
48
49 /*!
50   Create document.
51 */
52 void SalomeApp_Study::createDocument()
53 {
54   MESSAGE( "openDocument" );
55
56   // initialize myStudyDS, read HDF file
57   QString aName = newStudyName();
58   _PTR(Study) study ( SalomeApp_Application::studyMgr()->NewStudy( aName.latin1() ) );
59   if ( !study )
60     return;
61
62   setStudyDS( study );
63   setStudyName( aName );
64
65   // create myRoot
66   setRoot( new SalomeApp_RootObject( this ) );
67
68   CAM_Study::createDocument();
69
70   emit created( this );
71 }
72
73 //=======================================================================
74 // name    : openDocument
75 /*! Purpose : Open document*/
76 //=======================================================================
77 bool SalomeApp_Study::openDocument( const QString& theFileName )
78 {
79   MESSAGE( "openDocument" );
80
81   // initialize myStudyDS, read HDF file
82   _PTR(Study) study ( SalomeApp_Application::studyMgr()->Open( (char*) theFileName.latin1() ) );
83   if ( !study )
84     return false;
85
86   setStudyDS( study );
87
88   setRoot( new SalomeApp_RootObject( this ) ); // create myRoot
89
90   // update loaded data models: call open() and update() on them.
91   ModelList dm_s;
92   dataModels( dm_s );
93   for ( ModelListIterator it( dm_s ); it.current(); ++it )
94     openDataModel( studyName(), it.current() );
95
96   // this will build a SUIT_DataObject-s tree under myRoot member field
97   // passing "false" in order NOT to rebuild existing data models' trees - it was done in previous step
98   // but tree that corresponds to not-loaded data models will be updated any way. 
99   ((SalomeApp_Application*)application())->updateObjectBrowser( false ); 
100
101   bool res = CAM_Study::openDocument( theFileName );
102   emit opened( this );
103
104   return res;
105 }
106
107 //=======================================================================
108 // name    : loadDocument
109 /*! Purpose : Connects GUI study to SALOMEDS one already loaded into StudyManager*/
110 //=======================================================================
111 bool SalomeApp_Study::loadDocument( const QString& theStudyName )
112 {
113   MESSAGE( "loadDocument" );
114
115   // obtain myStudyDS from StudyManager
116   _PTR(Study) study ( SalomeApp_Application::studyMgr()->GetStudyByName( (char*) theStudyName.latin1() ) );
117   if ( !study )
118     return false;
119
120   setStudyDS( study );
121
122   setRoot( new SalomeApp_RootObject( this ) ); // create myRoot
123
124   //SRN: BugID IPAL9021, put there the same code as in a method openDocument
125
126   // update loaded data models: call open() and update() on them.
127   ModelList dm_s;
128   dataModels( dm_s );
129   for ( ModelListIterator it( dm_s ); it.current(); ++it )
130     openDataModel( studyName(), it.current() );
131
132   // this will build a SUIT_DataObject-s tree under myRoot member field
133   // passing "false" in order NOT to rebuild existing data models' trees - it was done in previous step
134   // but tree that corresponds to not-loaded data models will be updated any way. 
135   ((SalomeApp_Application*)application())->updateObjectBrowser( false ); 
136
137   bool res = CAM_Study::openDocument( theStudyName );
138   emit opened( this );
139
140   //SRN: BugID IPAL9021: End
141
142   return res;
143 }
144
145 //=======================================================================
146 // name    : saveDocumentAs
147 /*! Purpose : Save document */
148 //=======================================================================
149 bool SalomeApp_Study::saveDocumentAs( const QString& theFileName )
150 {
151   ModelList list; dataModels( list );
152
153   SalomeApp_DataModel* aModel = (SalomeApp_DataModel*)list.first();
154   for ( ; aModel; aModel = (SalomeApp_DataModel*)list.next() )
155     aModel->saveAs( theFileName, this );
156
157   // save SALOMEDS document
158   SUIT_ResourceMgr* resMgr = application()->resourceMgr();
159   if( !resMgr )
160     return false;
161
162   bool isMultiFile = resMgr->booleanValue( "Study", "multi_file", false ),
163        isAscii = resMgr->booleanValue( "Study", "ascii_file", true );
164   isAscii ? SalomeApp_Application::studyMgr()->SaveAsASCII( theFileName.latin1(), studyDS(), isMultiFile ) :
165             SalomeApp_Application::studyMgr()->SaveAs     ( theFileName.latin1(), studyDS(), isMultiFile );
166
167   bool res = CAM_Study::saveDocumentAs( theFileName );  //SRN: BugID IPAL9377, removed usage of uninitialized variable <res>
168
169   if ( res )
170     emit saved( this );
171
172   return res;
173 }
174
175 //=======================================================================
176 // name    : saveDocument
177 /*! Purpose : Save document */
178 //=======================================================================
179 void SalomeApp_Study::saveDocument()
180 {
181   ModelList list; dataModels( list );
182
183   SalomeApp_DataModel* aModel = (SalomeApp_DataModel*)list.first();
184   for ( ; aModel; aModel = (SalomeApp_DataModel*)list.next() )
185     aModel->save();
186
187   CAM_Study::saveDocument();
188
189   // save SALOMEDS document
190   SUIT_ResourceMgr* resMgr = application()->resourceMgr();
191   if( !resMgr )
192     return;
193   
194   bool isMultiFile = resMgr->booleanValue( "Study", "multi_file", false ),
195        isAscii = resMgr->booleanValue( "Study", "ascii_file", true );
196   isAscii ? SalomeApp_Application::studyMgr()->SaveASCII( studyDS(), isMultiFile ) :
197             SalomeApp_Application::studyMgr()->Save     ( studyDS(), isMultiFile );
198
199   emit saved( this );
200 }
201
202 //================================================================
203 // Function : closeDocument
204 /*! Purpose  : Close document */
205 //================================================================
206 void SalomeApp_Study::closeDocument(bool permanently)
207 {
208   // Inform everybody that this study is going to close when it's most safe to,
209   // i.e. in the very beginning
210   emit closed( this );
211
212   // close SALOMEDS document
213   _PTR(Study) studyPtr = studyDS();
214   if ( studyPtr )
215   {
216     if(permanently) SalomeApp_Application::studyMgr()->Close( studyPtr );
217     SALOMEDSClient_Study* aStudy = 0;
218     setStudyDS( _PTR(Study)(aStudy) );
219   }
220
221   CAM_Study::closeDocument(permanently);
222 }
223
224 //================================================================
225 // Function : isModified
226 /*! Purpose  : Check data model on modifications.*/
227 //================================================================
228 bool SalomeApp_Study::isModified() const
229 {
230   bool isAnyChanged = studyDS() && studyDS()->IsModified();
231   ModelList list; dataModels( list );
232
233   SalomeApp_DataModel* aModel = 0;
234   for ( QPtrListIterator<CAM_DataModel> it( list ); it.current() && !isAnyChanged; ++it ){
235     aModel = dynamic_cast<SalomeApp_DataModel*>( it.current() );
236     if ( aModel )
237       isAnyChanged = aModel->isModified();
238   }
239   return isAnyChanged; 
240 }
241
242 //================================================================
243 // Function : isSaved
244 /*! Purpose  : Check: data model is saved?*/
245 //================================================================
246 bool SalomeApp_Study::isSaved() const
247 {
248   bool isAllSaved = studyDS() && studyDS()->GetPersistentReference().size();
249   ModelList list; dataModels( list );
250
251   SalomeApp_DataModel* aModel = 0;
252   for ( QPtrListIterator<CAM_DataModel> it( list ); it.current() && isAllSaved; ++it ){
253     aModel = dynamic_cast<SalomeApp_DataModel*>( it.current() );
254     if ( aModel )
255       isAllSaved = aModel->isSaved();
256   }
257   return isAllSaved; 
258 }
259
260 /*!
261   Set studyDS.
262 */
263 void SalomeApp_Study::setStudyDS( const _PTR(Study)& s )
264 {
265   myStudyDS = s;
266 }
267
268 /*!
269   Insert data model.
270 */
271 void SalomeApp_Study::dataModelInserted (const CAM_DataModel* dm)
272 {
273   MESSAGE("SalomeApp_Study::dataModelInserted() : module name() = " << dm->module()->name());
274
275   CAM_Study::dataModelInserted(dm);
276
277   // Create SComponent for module, using default engine (CORBAless)
278   SalomeApp_Module* aModule = (SalomeApp_Module*)(dm->module());
279   if (aModule) {
280     QString anEngineIOR = aModule->engineIOR();
281     if (anEngineIOR.isEmpty()) { // CORBAless module
282       // Check SComponent existance
283       _PTR(SComponent) aComp = studyDS()->FindComponent(dm->module()->name());
284       if (!aComp) {
285         // Create SComponent
286         _PTR(StudyBuilder) aBuilder = studyDS()->NewBuilder();
287         aComp = aBuilder->NewComponent(dm->module()->name());
288
289         // Set default engine IOR
290         aBuilder->DefineComponentInstance(aComp, SalomeApp_Application::defaultEngineIOR().latin1());
291       }
292     }
293   }
294 }
295
296 /*!
297   Open data model
298 */
299 bool SalomeApp_Study::openDataModel( const QString& studyName, CAM_DataModel* dm )
300 {
301   if (!dm)
302     return false;
303
304   SalomeApp_DataModel* aDM = (SalomeApp_DataModel*)(dm);
305   if (aDM && aDM->open(studyName, this)) {
306     // Something has been read -> create data model tree
307     aDM->update(NULL, this);
308     return true;
309   }
310
311   return false;
312 }
313
314 /*!
315   Create new study name.
316 */
317 QString SalomeApp_Study::newStudyName() const
318 {
319   std::vector<std::string> studies = SalomeApp_Application::studyMgr()->GetOpenStudies();
320   QString prefix( "Study%1" ), newName, curName;
321   int i = 1, j, n = studies.size();
322   while ( newName.isEmpty() ){
323     curName = prefix.arg( i );
324     for ( j = 0 ; j < n; j++ ){
325       if ( !strcmp( studies[j].c_str(), curName.latin1() ) )
326         break;
327     }
328     if ( j == n )
329       newName = curName;
330     else
331       i++;
332   }
333   return newName;
334 }