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