Salome HOME
This file in LightApp package
[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   
103   emit opened( this );
104   study->IsSaved(true);
105   return res;
106 }
107
108 //=======================================================================
109 // name    : loadDocument
110 /*! Purpose : Connects GUI study to SALOMEDS one already loaded into StudyManager*/
111 //=======================================================================
112 bool SalomeApp_Study::loadDocument( const QString& theStudyName )
113 {
114   MESSAGE( "loadDocument" );
115
116   // obtain myStudyDS from StudyManager
117   _PTR(Study) study ( SalomeApp_Application::studyMgr()->GetStudyByName( (char*) theStudyName.latin1() ) );
118   if ( !study )
119     return false;
120
121   setStudyDS( study );
122
123   setRoot( new SalomeApp_RootObject( this ) ); // create myRoot
124
125   //SRN: BugID IPAL9021, put there the same code as in a method openDocument
126
127   // update loaded data models: call open() and update() on them.
128   ModelList dm_s;
129   dataModels( dm_s );
130   for ( ModelListIterator it( dm_s ); it.current(); ++it )
131     openDataModel( studyName(), it.current() );
132
133   // this will build a SUIT_DataObject-s tree under myRoot member field
134   // passing "false" in order NOT to rebuild existing data models' trees - it was done in previous step
135   // but tree that corresponds to not-loaded data models will be updated any way. 
136   ((SalomeApp_Application*)application())->updateObjectBrowser( false ); 
137
138   bool res = CAM_Study::openDocument( theStudyName );
139   emit opened( this );
140
141   //SRN: BugID IPAL9021: End
142
143   return res;
144 }
145
146 //=======================================================================
147 // name    : saveDocumentAs
148 /*! Purpose : Save document */
149 //=======================================================================
150 bool SalomeApp_Study::saveDocumentAs( const QString& theFileName )
151 {
152   ModelList list; dataModels( list );
153
154   SalomeApp_DataModel* aModel = (SalomeApp_DataModel*)list.first();
155   for ( ; aModel; aModel = (SalomeApp_DataModel*)list.next() )
156     aModel->saveAs( theFileName, this );
157
158   // save SALOMEDS document
159   SUIT_ResourceMgr* resMgr = application()->resourceMgr();
160   if( !resMgr )
161     return false;
162
163   bool isMultiFile = resMgr->booleanValue( "Study", "multi_file", false ),
164        isAscii = resMgr->booleanValue( "Study", "ascii_file", true );
165   isAscii ? SalomeApp_Application::studyMgr()->SaveAsASCII( theFileName.latin1(), studyDS(), isMultiFile ) :
166             SalomeApp_Application::studyMgr()->SaveAs     ( theFileName.latin1(), studyDS(), isMultiFile );
167
168   bool res = CAM_Study::saveDocumentAs( theFileName );  //SRN: BugID IPAL9377, removed usage of uninitialized variable <res>
169
170   if ( res )
171     emit saved( this );
172
173   return res;
174 }
175
176 //=======================================================================
177 // name    : saveDocument
178 /*! Purpose : Save document */
179 //=======================================================================
180 void SalomeApp_Study::saveDocument()
181 {
182   ModelList list; dataModels( list );
183
184   SalomeApp_DataModel* aModel = (SalomeApp_DataModel*)list.first();
185   for ( ; aModel; aModel = (SalomeApp_DataModel*)list.next() )
186     aModel->save();
187
188   CAM_Study::saveDocument();
189
190   // save SALOMEDS document
191   SUIT_ResourceMgr* resMgr = application()->resourceMgr();
192   if( !resMgr )
193     return;
194   
195   bool isMultiFile = resMgr->booleanValue( "Study", "multi_file", false ),
196        isAscii = resMgr->booleanValue( "Study", "ascii_file", true );
197   isAscii ? SalomeApp_Application::studyMgr()->SaveASCII( studyDS(), isMultiFile ) :
198             SalomeApp_Application::studyMgr()->Save     ( studyDS(), isMultiFile );
199
200   emit saved( this );
201 }
202
203 //================================================================
204 // Function : closeDocument
205 /*! Purpose  : Close document */
206 //================================================================
207 void SalomeApp_Study::closeDocument(bool permanently)
208 {
209   // Inform everybody that this study is going to close when it's most safe to,
210   // i.e. in the very beginning
211   emit closed( this );
212
213   // close SALOMEDS document
214   _PTR(Study) studyPtr = studyDS();
215   if ( studyPtr )
216   {
217     if(permanently) SalomeApp_Application::studyMgr()->Close( studyPtr );
218     SALOMEDSClient_Study* aStudy = 0;
219     setStudyDS( _PTR(Study)(aStudy) );
220   }
221
222   CAM_Study::closeDocument(permanently);
223 }
224
225 //================================================================
226 // Function : isModified
227 /*! Purpose  : Check data model on modifications.*/
228 //================================================================
229 bool SalomeApp_Study::isModified() const
230 {
231   bool isAnyChanged = studyDS() && studyDS()->IsModified();
232   ModelList list; dataModels( list );
233
234   SalomeApp_DataModel* aModel = 0;
235   for ( QPtrListIterator<CAM_DataModel> it( list ); it.current() && !isAnyChanged; ++it ){
236     aModel = dynamic_cast<SalomeApp_DataModel*>( it.current() );
237     if ( aModel )
238       isAnyChanged = aModel->isModified();
239   }
240   return isAnyChanged; 
241 }
242
243 //================================================================
244 // Function : isSaved
245 /*! Purpose  : Check: data model is saved?*/
246 //================================================================
247 bool SalomeApp_Study::isSaved() const
248 {
249   bool isAllSaved = studyDS() && studyDS()->GetPersistentReference().size();
250   ModelList list; dataModels( list );
251
252   SalomeApp_DataModel* aModel = 0;
253   for ( QPtrListIterator<CAM_DataModel> it( list ); it.current() && isAllSaved; ++it ){
254     aModel = dynamic_cast<SalomeApp_DataModel*>( it.current() );
255     if ( aModel )
256       isAllSaved = aModel->isSaved();
257   }
258   return isAllSaved; 
259 }
260
261 /*!
262   Set studyDS.
263 */
264 void SalomeApp_Study::setStudyDS( const _PTR(Study)& s )
265 {
266   myStudyDS = s;
267 }
268
269 /*!
270   Insert data model.
271 */
272 void SalomeApp_Study::dataModelInserted (const CAM_DataModel* dm)
273 {
274   MESSAGE("SalomeApp_Study::dataModelInserted() : module name() = " << dm->module()->name());
275
276   CAM_Study::dataModelInserted(dm);
277
278   // Create SComponent for module, using default engine (CORBAless)
279   SalomeApp_Module* aModule = (SalomeApp_Module*)(dm->module());
280   if (aModule) {
281     QString anEngineIOR = aModule->engineIOR();
282     if (anEngineIOR.isEmpty()) { // CORBAless module
283       // Check SComponent existance
284       _PTR(SComponent) aComp = studyDS()->FindComponent(dm->module()->name());
285       if (!aComp) {
286         // Create SComponent
287         _PTR(StudyBuilder) aBuilder = studyDS()->NewBuilder();
288         aComp = aBuilder->NewComponent(dm->module()->name());
289
290         // Set default engine IOR
291         aBuilder->DefineComponentInstance(aComp, SalomeApp_Application::defaultEngineIOR().latin1());
292       }
293     }
294   }
295 }
296
297 /*!
298   Open data model
299 */
300 bool SalomeApp_Study::openDataModel( const QString& studyName, CAM_DataModel* dm )
301 {
302   if (!dm)
303     return false;
304
305   SalomeApp_DataModel* aDM = (SalomeApp_DataModel*)(dm);
306   if (aDM && aDM->open(studyName, this)) {
307     // Something has been read -> create data model tree
308     aDM->update(NULL, this);
309     return true;
310   }
311
312   return false;
313 }
314
315 /*!
316   Create new study name.
317 */
318 QString SalomeApp_Study::newStudyName() const
319 {
320   std::vector<std::string> studies = SalomeApp_Application::studyMgr()->GetOpenStudies();
321   QString prefix( "Study%1" ), newName, curName;
322   int i = 1, j, n = studies.size();
323   while ( newName.isEmpty() ){
324     curName = prefix.arg( i );
325     for ( j = 0 ; j < n; j++ ){
326       if ( !strcmp( studies[j].c_str(), curName.latin1() ) )
327         break;
328     }
329     if ( j == n )
330       newName = curName;
331     else
332       i++;
333   }
334   return newName;
335 }
336
337 void SalomeApp_Study::deleteReferencesTo( _PTR( SObject ) obj )
338 {
339   _PTR(StudyBuilder) sb = studyDS()->NewBuilder();
340   std::vector<_PTR(SObject)> aRefs = studyDS()->FindDependances( obj );
341   for( int i=0, n=aRefs.size(); i<n; i++ )
342   {
343     _PTR( SObject ) o = aRefs[i];
344     if( o->GetFatherComponent()->ComponentDataType()==obj->GetFatherComponent()->ComponentDataType() )
345     {
346       sb->RemoveReference( o );
347       sb->RemoveObjectWithChildren( o );
348     }
349   }
350 }