Salome HOME
now study uses resources "multi_file" and "ascii_file" during document saving
[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   setRoot( new SalomeApp_RootObject( this ) ); // create myRoot
74
75   // update loaded data models: call open() and update() on them.
76   ModelList dm_s;
77   dataModels( dm_s );
78   for ( ModelListIterator it( dm_s ); it.current(); ++it )
79     openDataModel( studyName(), it.current() );
80
81   // this will build a SUIT_DataObject-s tree under myRoot member field
82   // passing "false" in order NOT to rebuild existing data models' trees - it was done in previous step
83   // but tree that corresponds to not-loaded data models will be updated any way. 
84   ((SalomeApp_Application*)application())->updateObjectBrowser( false ); 
85
86   bool res = CAM_Study::openDocument( theFileName );
87   emit opened( this );
88
89   return res;
90 }
91
92 //=======================================================================
93 // name    : loadDocument
94 // Purpose : Connects GUI study to SALOMEDS one already loaded into StudyManager
95 //=======================================================================
96 bool SalomeApp_Study::loadDocument( const QString& theStudyName )
97 {
98   MESSAGE( "loadDocument" );
99
100   // obtain myStudyDS from StudyManager
101   _PTR(Study) study ( SalomeApp_Application::studyMgr()->GetStudyByName( (char*) theStudyName.latin1() ) );
102   if ( !study )
103     return false;
104
105   setStudyDS( study );
106
107   setRoot( new SalomeApp_RootObject( this ) ); // create myRoot
108
109   //SRN: BugID IPAL9021, put there the same code as in a method openDocument
110
111   // update loaded data models: call open() and update() on them.
112   ModelList dm_s;
113   dataModels( dm_s );
114   for ( ModelListIterator it( dm_s ); it.current(); ++it )
115     openDataModel( studyName(), it.current() );
116
117   // this will build a SUIT_DataObject-s tree under myRoot member field
118   // passing "false" in order NOT to rebuild existing data models' trees - it was done in previous step
119   // but tree that corresponds to not-loaded data models will be updated any way. 
120   ((SalomeApp_Application*)application())->updateObjectBrowser( false ); 
121
122   bool res = CAM_Study::openDocument( theStudyName );
123   emit opened( this );
124
125   //SRN: BugID IPAL9021: End
126
127   return res;
128 }
129
130 //=======================================================================
131 // name    : saveDocumentAs
132 // Purpose : Save document
133 //=======================================================================
134 bool SalomeApp_Study::saveDocumentAs( const QString& theFileName )
135 {
136   ModelList list; dataModels( list );
137
138   SalomeApp_DataModel* aModel = (SalomeApp_DataModel*)list.first();
139   for ( ; aModel; aModel = (SalomeApp_DataModel*)list.next() )
140     aModel->saveAs( theFileName, this );
141
142   // save SALOMEDS document
143   SUIT_ResourceMgr* resMgr = application()->resourceMgr();
144   if( !resMgr )
145     return false;
146
147   bool isMultiFile = resMgr->booleanValue( "Study", "multi_file", false ),
148        isAscii = resMgr->booleanValue( "Study", "ascii_file", true );
149   isAscii ? SalomeApp_Application::studyMgr()->SaveAsASCII( theFileName.latin1(), studyDS(), isMultiFile ) :
150             SalomeApp_Application::studyMgr()->SaveAs     ( theFileName.latin1(), studyDS(), isMultiFile );
151
152   bool res = CAM_Study::saveDocumentAs( theFileName );  //SRN: BugID IPAL9377, removed usage of uninitialized variable <res>
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   SUIT_ResourceMgr* resMgr = application()->resourceMgr();
176   if( !resMgr )
177     return;
178   
179   bool isMultiFile = resMgr->booleanValue( "Study", "multi_file", false ),
180        isAscii = resMgr->booleanValue( "Study", "ascii_file", true );
181   isAscii ? SalomeApp_Application::studyMgr()->SaveASCII( studyDS(), isMultiFile ) :
182             SalomeApp_Application::studyMgr()->Save     ( studyDS(), isMultiFile );
183
184   emit saved( this );
185 }
186
187 //================================================================
188 // Function : closeDocument
189 // Purpose  : 
190 //================================================================
191 void SalomeApp_Study::closeDocument(bool permanently)
192 {
193   // Inform everybody that this study is going to close when it's most safe to,
194   // i.e. in the very beginning
195   emit closed( this );
196
197   // close SALOMEDS document
198   _PTR(Study) studyPtr = studyDS();
199   if ( studyPtr )
200   {
201     if(permanently) SalomeApp_Application::studyMgr()->Close( studyPtr );
202     SALOMEDSClient_Study* aStudy = 0;
203     setStudyDS( _PTR(Study)(aStudy) );
204   }
205
206   CAM_Study::closeDocument(permanently);
207 }
208
209 //================================================================
210 // Function : isModified
211 // Purpose  : 
212 //================================================================
213 bool SalomeApp_Study::isModified() const
214 {
215   bool isAnyChanged = studyDS() && studyDS()->IsModified();
216   ModelList list; dataModels( list );
217
218   SalomeApp_DataModel* aModel = 0;
219   for ( QPtrListIterator<CAM_DataModel> it( list ); it.current() && !isAnyChanged; ++it ){
220     aModel = dynamic_cast<SalomeApp_DataModel*>( it.current() );
221     if ( aModel )
222       isAnyChanged = aModel->isModified();
223   }
224   return isAnyChanged; 
225 }
226
227 //================================================================
228 // Function : isSaved
229 // Purpose  : 
230 //================================================================
231 bool SalomeApp_Study::isSaved() const
232 {
233   bool isAllSaved = studyDS() && studyDS()->GetPersistentReference().size();
234   ModelList list; dataModels( list );
235
236   SalomeApp_DataModel* aModel = 0;
237   for ( QPtrListIterator<CAM_DataModel> it( list ); it.current() && isAllSaved; ++it ){
238     aModel = dynamic_cast<SalomeApp_DataModel*>( it.current() );
239     if ( aModel )
240       isAllSaved = aModel->isSaved();
241   }
242   return isAllSaved; 
243 }
244
245 void SalomeApp_Study::setStudyDS( const _PTR(Study)& s )
246 {
247   myStudyDS = s;
248 }
249
250 void SalomeApp_Study::dataModelInserted (const CAM_DataModel* dm)
251 {
252   MESSAGE("SalomeApp_Study::dataModelInserted() : module name() = " << dm->module()->name());
253
254   CAM_Study::dataModelInserted(dm);
255
256   // Create SComponent for module, using default engine (CORBAless)
257   SalomeApp_Module* aModule = (SalomeApp_Module*)(dm->module());
258   if (aModule) {
259     QString anEngineIOR = aModule->engineIOR();
260     if (anEngineIOR.isEmpty()) { // CORBAless module
261       // Check SComponent existance
262       _PTR(SComponent) aComp = studyDS()->FindComponent(dm->module()->name());
263       if (!aComp) {
264         // Create SComponent
265         _PTR(StudyBuilder) aBuilder = studyDS()->NewBuilder();
266         aComp = aBuilder->NewComponent(dm->module()->name());
267
268         // Set default engine IOR
269         aBuilder->DefineComponentInstance(aComp, SalomeApp_Application::defaultEngineIOR().latin1());
270       }
271     }
272   }
273 }
274
275 bool SalomeApp_Study::openDataModel( const QString& studyName, CAM_DataModel* dm )
276 {
277   if (!dm)
278     return false;
279
280   SalomeApp_DataModel* aDM = (SalomeApp_DataModel*)(dm);
281   if (aDM && aDM->open(studyName, this)) {
282     // Something has been read -> create data model tree
283     aDM->update(NULL, this);
284     return true;
285   }
286
287   return false;
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 }