Salome HOME
Bug 9193:
[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 = CAM_Study::openDocument( theStudyName );
129
130   emit opened( this );
131
132   return res;  
133 }
134
135 //=======================================================================
136 // name    : saveDocumentAs
137 // Purpose : Save document
138 //=======================================================================
139 bool SalomeApp_Study::saveDocumentAs( const QString& theFileName )
140 {
141   ModelList list; dataModels( list );
142
143   SalomeApp_DataModel* aModel = (SalomeApp_DataModel*)list.first();
144   for ( ; aModel; aModel = (SalomeApp_DataModel*)list.next() )
145     aModel->saveAs( theFileName, this );
146
147   // save SALOMEDS document
148   bool isMultiFile = false, isAscii = false;// TODO: This information should be taken from preferences afterwards!
149    /* bool res = */isAscii ? SalomeApp_Application::studyMgr()->SaveAsASCII( theFileName.latin1(), studyDS(), isMultiFile ) :
150                   SalomeApp_Application::studyMgr()->SaveAs     ( theFileName.latin1(), studyDS(), isMultiFile );
151
152   bool res = res && CAM_Study::saveDocumentAs( theFileName );
153
154   if ( res )
155     emit saved( this );
156
157   return res;
158 }
159
160 //=======================================================================
161 // name    : saveDocument
162 // Purpose : Save document
163 //=======================================================================
164 void SalomeApp_Study::saveDocument()
165 {
166   ModelList list; dataModels( list );
167
168   SalomeApp_DataModel* aModel = (SalomeApp_DataModel*)list.first();
169   for ( ; aModel; aModel = (SalomeApp_DataModel*)list.next() )
170     aModel->save();
171
172   CAM_Study::saveDocument();
173
174   // save SALOMEDS document
175   bool isMultiFile = false, isAscii = false;// TODO: This information should be taken from preferences afterwards!
176   isAscii ? SalomeApp_Application::studyMgr()->SaveASCII( studyDS(), isMultiFile ) :
177             SalomeApp_Application::studyMgr()->Save     ( studyDS(), isMultiFile );
178
179   emit saved( this );
180 }
181
182 //================================================================
183 // Function : closeDocument
184 // Purpose  : 
185 //================================================================
186 void SalomeApp_Study::closeDocument()
187 {
188   // Inform everybody that this study is going to close when it's most safe to,
189   // i.e. in the very beginning
190   emit closed( this );
191
192   // close SALOMEDS document
193   _PTR(Study) studyPtr = studyDS();
194   if ( studyPtr )
195   {
196     SalomeApp_Application::studyMgr()->Close( studyPtr );
197     SALOMEDSClient_Study* aStudy = 0;
198     setStudyDS( _PTR(Study)(aStudy) );
199   }
200
201   CAM_Study::closeDocument();
202 }
203
204 //================================================================
205 // Function : isModified
206 // Purpose  : 
207 //================================================================
208 bool SalomeApp_Study::isModified() const
209 {
210   bool isAnyChanged = studyDS() && studyDS()->IsModified();
211   ModelList list; dataModels( list );
212
213   SalomeApp_DataModel* aModel = 0;
214   for ( QPtrListIterator<CAM_DataModel> it( list ); it.current() && !isAnyChanged; ++it ){
215     aModel = dynamic_cast<SalomeApp_DataModel*>( it.current() );
216     if ( aModel )
217       isAnyChanged = aModel->isModified();
218   }
219   return isAnyChanged; 
220 }
221
222 //================================================================
223 // Function : isSaved
224 // Purpose  : 
225 //================================================================
226 bool SalomeApp_Study::isSaved() const
227 {
228   bool isAllSaved = studyDS() && studyDS()->GetPersistentReference().size();
229   ModelList list; dataModels( list );
230
231   SalomeApp_DataModel* aModel = 0;
232   for ( QPtrListIterator<CAM_DataModel> it( list ); it.current() && isAllSaved; ++it ){
233     aModel = dynamic_cast<SalomeApp_DataModel*>( it.current() );
234     if ( aModel )
235       isAllSaved = aModel->isSaved();
236   }
237   return isAllSaved; 
238 }
239
240 void SalomeApp_Study::setStudyDS( const _PTR(Study)& s )
241 {
242   myStudyDS = s;
243 }
244
245 void SalomeApp_Study::dataModelInserted (const CAM_DataModel* dm)
246 {
247   MESSAGE("SalomeApp_Study::dataModelInserted() : module name() = " << dm->module()->name());
248
249   CAM_Study::dataModelInserted(dm);
250
251   // Create SComponent for module, using default engine (CORBAless)
252   SalomeApp_Module* aModule = (SalomeApp_Module*)(dm->module());
253   if (aModule) {
254     QString anEngineIOR = aModule->engineIOR();
255     if (anEngineIOR.isEmpty()) { // CORBAless module
256       // Check SComponent existance
257       _PTR(SComponent) aComp = studyDS()->FindComponent(dm->module()->name());
258       if (!aComp) {
259         // Create SComponent
260         _PTR(StudyBuilder) aBuilder = studyDS()->NewBuilder();
261         aComp = aBuilder->NewComponent(dm->module()->name());
262
263         // Set default engine IOR
264         aBuilder->DefineComponentInstance(aComp, SalomeApp_Application::defaultEngineIOR().latin1());
265       }
266     }
267   }
268 }
269
270 bool SalomeApp_Study::openDataModel( const QString& studyName, CAM_DataModel* dm )
271 {
272   if (!dm)
273     return false;
274
275   SalomeApp_DataModel* aDM = (SalomeApp_DataModel*)(dm);
276   if (aDM && aDM->open(studyName, this)) {
277     // Something has been read -> create data model tree
278     aDM->update(NULL, this);
279     return true;
280   }
281
282   return false;
283 }
284
285 void SalomeApp_Study::updateModelRoot( const CAM_DataModel* dm )
286 {
287   CAM_Study::updateModelRoot( dm );
288   ((SalomeApp_Application*)application())->objectBrowser()->updateTree();
289 }
290
291 QString SalomeApp_Study::newStudyName() const
292 {
293   std::vector<std::string> studies = SalomeApp_Application::studyMgr()->GetOpenStudies();
294   QString prefix( "Study%1" ), newName, curName;
295   int i = 1, j, n = studies.size();
296   while ( newName.isEmpty() ){
297     curName = prefix.arg( i );
298     for ( j = 0 ; j < n; j++ ){
299       if ( !strcmp( studies[j].c_str(), curName.latin1() ) )
300         break;
301     }
302     if ( j == n )
303       newName = curName;
304     else
305       i++;
306   }
307   return newName;
308 }