Salome HOME
add SVTK resources
[modules/gui.git] / src / LightApp / LightApp_Study.cxx
1 #include "LightApp_Study.h"
2
3 #include "CAM_DataModel.h"
4 #include "LightApp_Application.h"
5 #include "LightApp_DataModel.h"
6 #include "LightApp_DataObject.h"
7 #include "LightApp_RootObject.h"
8 #include "LightApp_Driver.h"
9
10 #include "SUIT_ResourceMgr.h"
11 #include "SUIT_DataObjectIterator.h"
12
13 #include <OB_Browser.h>
14
15 #include <TCollection_AsciiString.hxx> 
16
17 #include <OSD_Path.hxx>
18 #include <OSD_File.hxx>
19 #include <OSD_Directory.hxx>
20 #include <OSD_Process.hxx>
21 #include <OSD_Directory.hxx>
22 #include <OSD_Protection.hxx>
23 #include <OSD_SingleProtection.hxx>
24 #include <OSD_FileIterator.hxx>
25
26 #include <set>
27 #include <qstring.h>
28
29 /*!
30   Constructor.
31 */
32 LightApp_Study::LightApp_Study( SUIT_Application* app )
33 : CAM_Study( app )
34 {
35   myDriver = new LightApp_Driver();
36 }
37  
38 /*!
39   Destructor.
40 */
41 LightApp_Study::~LightApp_Study()
42 {
43 }
44
45 /*!
46   Create document.
47 */
48 void LightApp_Study::createDocument()
49 {
50   // create myRoot
51   setRoot( new LightApp_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 LightApp_Study::openDocument( const QString& theFileName )
63 {
64   myDriver->ClearDriverContents();
65   // create files for models from theFileName
66   if( !openStudyData(theFileName))
67     return false;
68
69   setRoot( new LightApp_RootObject( this ) ); // create myRoot
70
71   // update loaded data models: call open() and update() on them.
72   ModelList dm_s;
73   dataModels( dm_s );
74   for ( ModelListIterator it( dm_s ); it.current(); ++it )
75     openDataModel( studyName(), it.current() );
76   // this will build a SUIT_DataObject-s tree under myRoot member field
77   // passing "false" in order NOT to rebuild existing data models' trees - it was done in previous step
78   // but tree that corresponds to not-loaded data models will be updated any way. 
79   ((LightApp_Application*)application())->updateObjectBrowser( false ); 
80
81   bool res = CAM_Study::openDocument( theFileName );
82
83   emit opened( this );
84   return res;
85 }
86
87 //=======================================================================
88 // name    : loadDocument
89 /*! Purpose : Load document */
90 //=======================================================================
91 bool LightApp_Study::loadDocument( const QString& theStudyName )
92 {
93   myDriver->ClearDriverContents();
94   if( !openStudyData(theStudyName))
95     return false;
96
97   setRoot( new LightApp_RootObject( this ) ); // create myRoot
98
99   //SRN: BugID IPAL9021, put there the same code as in a method openDocument
100
101   // update loaded data models: call open() and update() on them.
102   ModelList dm_s;
103   dataModels( dm_s );
104
105   for ( ModelListIterator it( dm_s ); it.current(); ++it )
106     openDataModel( studyName(), it.current() );
107
108   // this will build a SUIT_DataObject-s tree under myRoot member field
109   // passing "false" in order NOT to rebuild existing data models' trees - it was done in previous step
110   // but tree that corresponds to not-loaded data models will be updated any way. 
111   ((LightApp_Application*)application())->updateObjectBrowser( false ); 
112
113   bool res = CAM_Study::openDocument( theStudyName );
114   emit opened( this );
115   //SRN: BugID IPAL9021: End
116   return res;
117 }
118
119 //=======================================================================
120 // name    : saveDocumentAs
121 /*! Purpose : Save document */
122 //=======================================================================
123 bool LightApp_Study::saveDocumentAs( const QString& theFileName )
124 {
125   SUIT_ResourceMgr* resMgr = application()->resourceMgr();
126   if( !resMgr )
127     return false;
128
129   ModelList list; 
130   dataModels( list );
131
132   LightApp_DataModel* aModel = (LightApp_DataModel*)list.first();
133
134   QStringList listOfFiles;
135   bool isMultiFile = resMgr->booleanValue( "Study", "multi_file", false );
136   for ( ; aModel; aModel = (LightApp_DataModel*)list.next() ) 
137   {
138     std::vector<std::string> anOldList = myDriver->GetListOfFiles( aModel->module()->name() );
139     listOfFiles.clear();
140     aModel->saveAs( theFileName, this, listOfFiles );
141     if ( !listOfFiles.isEmpty() )
142       saveModuleData(aModel->module()->name(), listOfFiles);
143
144     // Remove files if necessary. File is removed if it was in the list of files before
145     // saving and it is not contained in the list after saving. This provides correct 
146     // removing previous temporary files. These files are not removed before saving
147     // because they may be required for it.
148
149     std::vector<std::string> aNewList = myDriver->GetListOfFiles( aModel->module()->name() );
150     
151     std::set<std::string> aNewNames;
152     std::set<std::string> toRemove;
153     int i, n;
154     for( i = 0, n = aNewList.size(); i < n; i++ )
155       aNewNames.insert( aNewList[ i ] );
156     for( i = 0, n = anOldList.size(); i < n; i++ )
157     {
158       if ( i == 0 ) // directory is always inserted in list
159         toRemove.insert( anOldList[ i ] );
160       else if ( aNewNames.find( anOldList[ i ] ) == aNewNames.end() )
161         toRemove.insert( anOldList[ i ] );
162     }
163         
164     std::vector<std::string> toRemoveList( toRemove.size() );
165     std::set<std::string>::iterator anIter;
166     for( anIter = toRemove.begin(), i = 0; anIter != toRemove.end(); ++anIter, ++i )
167       toRemoveList[ i ] = *anIter;
168
169     
170     myDriver->RemoveFiles( toRemoveList, isMultiFile );
171   }
172
173   bool res = saveStudyData(theFileName);
174   res = res && CAM_Study::saveDocumentAs( theFileName );
175   //SRN: BugID IPAL9377, removed usage of uninitialized variable <res>
176   if ( res )
177     emit saved( this );
178
179   return res;
180 }
181
182 //=======================================================================
183 // name    : saveDocument
184 /*! Purpose : Save document */
185 //=======================================================================
186 bool LightApp_Study::saveDocument()
187 {
188   ModelList list; dataModels( list );
189
190   LightApp_DataModel* aModel = (LightApp_DataModel*)list.first();
191
192   myDriver->ClearDriverContents();
193   QStringList listOfFiles;
194   for ( ; aModel; aModel = (LightApp_DataModel*)list.next() ) {
195     listOfFiles.clear();
196     aModel->save( listOfFiles );
197     saveModuleData(aModel->module()->name(), listOfFiles);
198   }
199
200   bool res = saveStudyData(studyName());
201   res = res && CAM_Study::saveDocument();
202   if (res)
203     emit saved( this );
204
205   return res;
206 }
207
208 //================================================================
209 // Function : closeDocument
210 /*! Purpose  : Close document */
211 //================================================================
212 void LightApp_Study::closeDocument(bool permanently)
213 {
214   // Remove temporary files
215   ModelList aList;
216   dataModels( aList );
217   myDriver->ClearDriverContents();
218
219   // Inform everybody that this study is going to close when it's most safe to,
220   // i.e. in the very beginning
221   emit closed( this );
222
223   CAM_Study::closeDocument(permanently);
224 }
225
226 //================================================================
227 // Function : referencedToEntry
228 /*! Purpose  : Return current entry*/
229 //================================================================
230 QString LightApp_Study::referencedToEntry( const QString& entry ) const
231 {
232   return entry;
233 }
234
235 //================================================================
236 // Function : children
237 /*! Purpose : Return entries of children of object*/
238 //================================================================
239 void LightApp_Study::children( const QString&, QStringList& ) const
240 {
241 }
242
243 //================================================================
244 // Function : isComponent
245 /*! Purpose : Return true if entry corresponds to component*/
246 //================================================================
247 bool LightApp_Study::isComponent( const QString& entry ) const
248 {
249   return false;
250 }
251
252 //================================================================
253 // Function : componentDataType
254 /*! Purpose  : Return component data type from entry*/
255 //================================================================
256 QString LightApp_Study::componentDataType( const QString& entry ) const
257 {
258   LightApp_DataObject* aCurObj;
259   for ( SUIT_DataObjectIterator it( root(), SUIT_DataObjectIterator::DepthLeft ); it.current(); ++it ) {
260     aCurObj = dynamic_cast<LightApp_DataObject*>( it.current() );
261     if ( aCurObj && aCurObj->entry() == entry ) {
262       return aCurObj->componentDataType();
263     }
264   }
265   return "";
266 }
267
268 //================================================================
269 // Function : isModified
270 // Purpose  : 
271 //================================================================
272 bool LightApp_Study::isModified() const
273 {
274   bool isAnyChanged = CAM_Study::isModified();
275   ModelList list; dataModels( list );
276
277   LightApp_DataModel* aModel = 0;
278   for ( QPtrListIterator<CAM_DataModel> it( list ); it.current() && !isAnyChanged; ++it ){
279     aModel = dynamic_cast<LightApp_DataModel*>( it.current() );
280     if ( aModel )
281       isAnyChanged = aModel->isModified();
282   }
283   return isAnyChanged; 
284 }
285
286 //================================================================
287 // Function : isSaved
288 /*! Purpose  : Check: data model is saved?*/
289 //================================================================
290 bool LightApp_Study::isSaved() const
291 {
292   return CAM_Study::isSaved();
293 }
294
295 //=======================================================================
296 // name    : saveModuleData
297 /*! Purpose :  Create SComponent for module, necessary for SalomeApp study */
298 //=======================================================================
299 void LightApp_Study::addComponent(const CAM_DataModel* dm)
300 {
301 }
302
303 //=======================================================================
304 // name    : saveModuleData
305 /*! Purpose : save list file for module 'theModuleName' */
306 //=======================================================================
307 void LightApp_Study::saveModuleData(QString theModuleName, QStringList theListOfFiles)
308 {
309   int aNb = theListOfFiles.count();
310   if ( aNb == 0 )
311     return;
312
313   std::vector<std::string> aListOfFiles ( aNb );
314   int anIndex = 0;
315   for ( QStringList::Iterator it = theListOfFiles.begin(); it != theListOfFiles.end(); ++it ) {
316     if ( (*it).isEmpty() )
317       continue;
318     aListOfFiles[anIndex] = (*it).latin1();
319     anIndex++;
320   }
321   myDriver->SetListOfFiles(theModuleName, aListOfFiles);
322 }
323
324 //=======================================================================
325 // name    : openModuleData
326 /*! Purpose : gets list of file for module 'theModuleNam' */
327 //=======================================================================
328 void LightApp_Study::openModuleData(QString theModuleName, QStringList& theListOfFiles)
329 {
330   std::vector<std::string> aListOfFiles =  myDriver->GetListOfFiles(theModuleName);
331   int i, aLength = aListOfFiles.size() - 1;
332   if (aLength < 0)
333     return;
334
335   //Get a temporary directory for saved a file
336   theListOfFiles.append(aListOfFiles[0].c_str());
337   for(i = 0; i < aLength; i++)
338     theListOfFiles.append(aListOfFiles[i+1].c_str());
339 }
340
341 //=======================================================================
342 // name    : saveStudyData
343 /*! Purpose : save data from study */
344 //=======================================================================
345 bool LightApp_Study::saveStudyData( const QString& theFileName )
346 {
347   ModelList list; dataModels( list );
348   SUIT_ResourceMgr* resMgr = application()->resourceMgr();
349   if( !resMgr )
350     return false;
351   bool isMultiFile = resMgr->booleanValue( "Study", "multi_file", false );
352
353   bool aRes = myDriver->SaveDatasInFile(theFileName.latin1(), isMultiFile);
354   return aRes;
355 }
356
357 //=======================================================================
358 // name    : openStudyData
359 /*! Purpose : open data for study */
360 //=======================================================================
361 bool LightApp_Study::openStudyData( const QString& theFileName )
362 {
363   SUIT_ResourceMgr* resMgr = application()->resourceMgr();
364   if( !resMgr )
365     return false;
366   bool isMultiFile = resMgr->booleanValue( "Study", "multi_file", false );
367
368   bool aRes = myDriver->ReadDatasFromFile(theFileName.latin1(), isMultiFile);
369   return aRes;
370 }
371
372 //================================================================
373 // Function : openDataModel
374 /*! Purpose  : Open data model */
375 //================================================================
376 bool LightApp_Study::openDataModel( const QString& studyName, CAM_DataModel* dm )
377 {
378   if (!dm)
379     return false;
380
381   QStringList listOfFiles;
382   openModuleData(dm->module()->name(), listOfFiles);
383   if (dm && dm->open(studyName, this, listOfFiles)) {
384     // Something has been read -> create data model tree
385     LightApp_DataModel* aDM = dynamic_cast<LightApp_DataModel*>( dm );
386     if ( aDM )
387       aDM->update(NULL, this);
388     return true;
389   }
390   return false;
391 }
392
393 //================================================================
394 // Function : GetTmpDir
395 /*! Purpose  : to be used by modules*/
396 //================================================================
397 std::string LightApp_Study::GetTmpDir (const char* theURL,
398                                        const bool  isMultiFile)
399 {
400   return myDriver->GetTmpDir(theURL, isMultiFile);
401 }
402
403 //================================================================
404 // Function : GetListOfFiles
405 /*! Purpose  : to be used by modules*/
406 //================================================================
407 std::vector<std::string> LightApp_Study::GetListOfFiles(const char* theModuleName) const
408 {
409   std::vector<std::string> aListOfFiles;
410   aListOfFiles = myDriver->GetListOfFiles(theModuleName);
411   return aListOfFiles;
412 }
413
414 //================================================================
415 // Function : SetListOfFiles
416 /*! Purpose  : to be used by modules*/
417 //================================================================
418 void LightApp_Study::SetListOfFiles (const char* theModuleName, const std::vector<std::string> theListOfFiles)
419 {
420   myDriver->SetListOfFiles(theModuleName, theListOfFiles);
421 }
422
423 //================================================================
424 // Function : RemoveTemporaryFiles
425 /*! Purpose  : to be used by modules*/
426 //================================================================
427 void LightApp_Study::RemoveTemporaryFiles (const char* theModuleName, const bool isMultiFile) const
428 {
429   if (isMultiFile)
430     return;
431   bool isDirDeleted = true;
432   myDriver->RemoveTemporaryFiles(theModuleName, isDirDeleted);
433 }
434
435 //================================================================
436 // Function : RemoveTemporaryFiles
437 /*! Purpose  : to be used by modules*/
438 //================================================================
439 void LightApp_Study::components( QStringList& comp ) const
440 {
441   DataObjectList children = root()->children();
442   DataObjectList::const_iterator anIt = children.begin(), aLast = children.end();
443   for( ; anIt!=aLast; anIt++ )
444   {
445     LightApp_DataObject* obj = dynamic_cast<LightApp_DataObject*>( *anIt );
446     if( obj && obj->entry()!="Interface Applicative" )
447       comp.append( obj->entry() );
448   }
449 }
450