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