Salome HOME
Application::onLoadDoc() method implementation (for VISU batchmode tests)
[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 SalomeApp_Study::SalomeApp_Study( SUIT_Application* app )
16 : CAM_Study( app )
17 {
18 }  
19
20 SalomeApp_Study::~SalomeApp_Study()
21 {
22 }
23
24 int SalomeApp_Study::id() const
25 {
26   int id = -1;
27   if ( myStudyDS )
28     id = studyDS()->StudyId();
29   return id;
30 }
31
32 _PTR(Study) SalomeApp_Study::studyDS() const
33 {
34   return myStudyDS;
35 }
36
37 void SalomeApp_Study::createDocument()
38 {
39   MESSAGE( "openDocument" );
40
41   // initialize myStudyDS, read HDF file
42   QString aName = newStudyName();
43   _PTR(Study) study ( SalomeApp_Application::studyMgr()->NewStudy( aName.latin1() ) );
44   if ( !study )
45     return;
46
47   setStudyDS( study );
48   setStudyName( aName );
49
50   // create myRoot
51   setRoot( new SalomeApp_RootObject( this ) );
52
53   CAM_Study::createDocument();
54
55   emit created( this );
56 }
57
58 //=======================================================================
59 // name    : openDocument
60 // Purpose : Open document
61 //=======================================================================
62 bool SalomeApp_Study::openDocument( const QString& theFileName )
63 {
64   MESSAGE( "openDocument" );
65
66   // initialize myStudyDS, read HDF file
67   _PTR(Study) study ( SalomeApp_Application::studyMgr()->Open( (char*) theFileName.latin1() ) );
68   if ( !study )
69     return false;
70
71   setStudyDS( study );
72
73   // build a SUIT_DataObject-s tree under myRoot member field
74   // 1. create myRoot
75   setRoot( new SalomeApp_RootObject( this ) );
76   // 2. iterate through all components and create corresponding sub-trees under them
77   _PTR(SComponentIterator) it ( studyDS()->NewComponentIterator() );
78   for ( ; it->More(); it->Next() ) {
79     // don't use shared_ptr here, for Data Object will take 
80     // ownership of this pointer
81     _PTR(SComponent) aComponent ( it->Value() ); 
82
83     if ( aComponent->ComponentDataType() == "Interface Applicative" )
84       continue; // skip the magic "Interface Applicative" component
85     
86     SalomeApp_DataModel::BuildTree( aComponent, root(), this );
87   }
88
89   bool res = CAM_Study::openDocument( theFileName );
90
91   emit opened( this );
92
93   return res;
94 }
95
96 //=======================================================================
97 // name    : loadDocument
98 // Purpose : Connects GUI study to SALOMEDS one already loaded into StudyManager
99 //=======================================================================
100 bool SalomeApp_Study::loadDocument( const QString& theStudyName )
101 {
102   MESSAGE( "loadDocument" );
103
104   // obtain myStudyDS from StudyManager
105   _PTR(Study) study ( SalomeApp_Application::studyMgr()->GetStudyByName( (char*) theStudyName.latin1() ) );
106   if ( !study )
107     return false;
108
109   setStudyDS( study );
110
111   // build a SUIT_DataObject-s tree under myRoot member field
112   // 1. create myRoot
113   setRoot( new SalomeApp_RootObject( this ) );
114   // 2. iterate through all components and create corresponding sub-trees under them
115   _PTR(SComponentIterator) it ( studyDS()->NewComponentIterator() );
116   for ( ; it->More(); it->Next() ) {
117     // don't use shared_ptr here, for Data Object will take 
118     // ownership of this pointer
119     _PTR(SComponent) aComponent ( it->Value() ); 
120
121     if ( aComponent->ComponentDataType() == "Interface Applicative" )
122       continue; // skip the magic "Interface Applicative" component
123
124     SalomeApp_DataModel::BuildTree( aComponent, root(), this );
125   }
126
127   // TODO: potentially unsafe call, since base study's openDocument() might try to access the file directly - to be improved
128   //bool res = true;
129   bool res = CAM_Study::openDocument( theStudyName );
130
131   //emit opened( this );
132
133   return res;
134 }
135
136 //=======================================================================
137 // name    : saveDocumentAs
138 // Purpose : Save document
139 //=======================================================================
140 bool SalomeApp_Study::saveDocumentAs( const QString& theFileName )
141 {
142   ModelList list; dataModels( list );
143
144   SalomeApp_DataModel* aModel = (SalomeApp_DataModel*)list.first();
145   for ( ; aModel; aModel = (SalomeApp_DataModel*)list.next() )
146     aModel->saveAs( theFileName, this );
147
148   // save SALOMEDS document
149   bool isMultiFile = false, isAscii = false;// TODO: This information should be taken from preferences afterwards!
150    /* bool res = */isAscii ? SalomeApp_Application::studyMgr()->SaveAsASCII( theFileName.latin1(), studyDS(), isMultiFile ) :
151                   SalomeApp_Application::studyMgr()->SaveAs     ( theFileName.latin1(), studyDS(), isMultiFile );
152
153   bool res = res && CAM_Study::saveDocumentAs( theFileName );
154
155   if ( res )
156     emit saved( this );
157
158   return res;
159 }
160
161 //=======================================================================
162 // name    : saveDocument
163 // Purpose : Save document
164 //=======================================================================
165 void SalomeApp_Study::saveDocument()
166 {
167   ModelList list; dataModels( list );
168
169   SalomeApp_DataModel* aModel = (SalomeApp_DataModel*)list.first();
170   for ( ; aModel; aModel = (SalomeApp_DataModel*)list.next() )
171     aModel->save();
172
173   CAM_Study::saveDocument();
174
175   // save SALOMEDS document
176   bool isMultiFile = false, isAscii = false;// TODO: This information should be taken from preferences afterwards!
177   isAscii ? SalomeApp_Application::studyMgr()->SaveASCII( studyDS(), isMultiFile ) :
178             SalomeApp_Application::studyMgr()->Save     ( studyDS(), isMultiFile );
179
180   emit saved( this );
181 }
182
183 //================================================================
184 // Function : closeDocument
185 // Purpose  : 
186 //================================================================
187 void SalomeApp_Study::closeDocument()
188 {
189   // Inform everybody that this study is going to close when it's most safe to,
190   // i.e. in the very beginning
191   emit closed( this );
192
193   // close SALOMEDS document
194   _PTR(Study) studyPtr = studyDS();
195   if ( studyPtr )
196   {
197     SalomeApp_Application::studyMgr()->Close( studyPtr );
198     SALOMEDSClient_Study* aStudy = 0;
199     setStudyDS( _PTR(Study)(aStudy) );
200   }
201
202   CAM_Study::closeDocument();
203 }
204
205 //================================================================
206 // Function : isModified
207 // Purpose  : 
208 //================================================================
209 bool SalomeApp_Study::isModified() const
210 {
211   bool isAnyChanged = studyDS() && studyDS()->IsModified();
212   ModelList list; dataModels( list );
213
214   SalomeApp_DataModel* aModel = 0;
215   for ( QPtrListIterator<CAM_DataModel> it( list ); it.current() && !isAnyChanged; ++it ){
216     aModel = dynamic_cast<SalomeApp_DataModel*>( it.current() );
217     if ( aModel )
218       isAnyChanged = aModel->isModified();
219   }
220   return isAnyChanged; 
221 }
222
223 //================================================================
224 // Function : isSaved
225 // Purpose  : 
226 //================================================================
227 bool SalomeApp_Study::isSaved() const
228 {
229   bool isAllSaved = studyDS() && studyDS()->GetPersistentReference().size();
230   ModelList list; dataModels( list );
231
232   SalomeApp_DataModel* aModel = 0;
233   for ( QPtrListIterator<CAM_DataModel> it( list ); it.current() && isAllSaved; ++it ){
234     aModel = dynamic_cast<SalomeApp_DataModel*>( it.current() );
235     if ( aModel )
236       isAllSaved = aModel->isSaved();
237   }
238   return isAllSaved; 
239 }
240
241 void SalomeApp_Study::setStudyDS( const _PTR(Study)& s )
242 {
243   myStudyDS = s;
244 }
245
246 void SalomeApp_Study::dataModelInserted (const CAM_DataModel* dm)
247 {
248   MESSAGE("SalomeApp_Study::dataModelInserted() : module name() = " << dm->module()->name());
249
250   CAM_Study::dataModelInserted(dm);
251
252   // Create SComponent for module, using default engine (CORBAless)
253   SalomeApp_Module* aModule = (SalomeApp_Module*)(dm->module());
254   if (aModule) {
255     QString anEngineIOR = aModule->engineIOR();
256     if (anEngineIOR.isEmpty()) { // CORBAless module
257       // Check SComponent existance
258       _PTR(SComponent) aComp = studyDS()->FindComponent(dm->module()->name());
259       if (!aComp) {
260         // Create SComponent
261         _PTR(StudyBuilder) aBuilder = studyDS()->NewBuilder();
262         aComp = aBuilder->NewComponent(dm->module()->name());
263
264         // Set default engine IOR
265         aBuilder->DefineComponentInstance(aComp, SalomeApp_Application::defaultEngineIOR().latin1());
266       }
267     }
268   }
269 }
270
271 bool SalomeApp_Study::openDataModel( const QString& studyName, CAM_DataModel* dm )
272 {
273   if (!dm)
274     return false;
275
276   SalomeApp_DataModel* aDM = (SalomeApp_DataModel*)(dm);
277   if (aDM && aDM->open(studyName, this)) {
278     // Something has been read -> create data model tree
279     aDM->update(NULL, this);
280     return true;
281   }
282
283   return false;
284 }
285
286 void SalomeApp_Study::updateModelRoot( const CAM_DataModel* dm )
287 {
288   CAM_Study::updateModelRoot( dm );
289   ((SalomeApp_Application*)application())->objectBrowser()->updateTree();
290 }
291
292 QString SalomeApp_Study::newStudyName() const
293 {
294   std::vector<std::string> studies = SalomeApp_Application::studyMgr()->GetOpenStudies();
295   QString prefix( "Study%1" ), newName, curName;
296   int i = 1, j, n = studies.size();
297   while ( newName.isEmpty() ){
298     curName = prefix.arg( i );
299     for ( j = 0 ; j < n; j++ ){
300       if ( !strcmp( studies[j].c_str(), curName.latin1() ) )
301         break;
302     }
303     if ( j == n )
304       newName = curName;
305     else
306       i++;
307   }
308   return newName;
309 }