1 #include "SalomeApp_Study.h"
3 #include "SalomeApp_Module.h"
4 #include "SalomeApp_DataModel.h"
5 #include "SalomeApp_DataObject.h"
6 #include "SalomeApp_Application.h"
7 #include "SalomeApp_Engine_i.hxx"
9 #include "LightApp_RootObject.h"
11 #include <OB_Browser.h>
13 #include <SUIT_ResourceMgr.h>
17 #include "utilities.h"
21 #include "SALOMEDS_Tool.hxx"
23 #include <SALOMEconfig.h>
24 #include CORBA_SERVER_HEADER(SALOME_Exception)
29 SalomeApp_Study::SalomeApp_Study( SUIT_Application* app )
30 : LightApp_Study( app )
37 SalomeApp_Study::~SalomeApp_Study()
44 int SalomeApp_Study::id() const
48 id = studyDS()->StudyId();
55 _PTR(Study) SalomeApp_Study::studyDS() const
63 void SalomeApp_Study::createDocument()
65 MESSAGE( "openDocument" );
67 // initialize myStudyDS, read HDF file
68 QString aName = newStudyName();
69 _PTR(Study) study ( SalomeApp_Application::studyMgr()->NewStudy( aName.latin1() ) );
74 setStudyName( aName );
77 setRoot( new LightApp_RootObject( this ) );
79 CAM_Study::createDocument();
83 //=======================================================================
84 // name : openDocument
85 /*! Purpose : Open document*/
86 //=======================================================================
87 bool SalomeApp_Study::openDocument( const QString& theFileName )
89 MESSAGE( "openDocument" );
91 // initialize myStudyDS, read HDF file
92 _PTR(Study) study ( SalomeApp_Application::studyMgr()->Open( (char*) theFileName.latin1() ) );
98 setRoot( new LightApp_RootObject( this ) ); // create myRoot
100 // update loaded data models: call open() and update() on them.
103 for ( ModelListIterator it( dm_s ); it.current(); ++it )
104 openDataModel( studyName(), it.current() );
106 // this will build a SUIT_DataObject-s tree under myRoot member field
107 // passing "false" in order NOT to rebuild existing data models' trees - it was done in previous step
108 // but tree that corresponds to not-loaded data models will be updated any way.
109 ((SalomeApp_Application*)application())->updateObjectBrowser( false );
111 bool res = CAM_Study::openDocument( theFileName );
114 study->IsSaved(true);
118 //=======================================================================
119 // name : loadDocument
120 /*! Purpose : Connects GUI study to SALOMEDS one already loaded into StudyManager*/
121 //=======================================================================
122 bool SalomeApp_Study::loadDocument( const QString& theStudyName )
124 MESSAGE( "loadDocument" );
126 // obtain myStudyDS from StudyManager
127 _PTR(Study) study ( SalomeApp_Application::studyMgr()->GetStudyByName( (char*) theStudyName.latin1() ) );
133 setRoot( new LightApp_RootObject( this ) ); // create myRoot
135 //SRN: BugID IPAL9021, put there the same code as in a method openDocument
137 // update loaded data models: call open() and update() on them.
141 for ( ModelListIterator it( dm_s ); it.current(); ++it )
142 openDataModel( studyName(), it.current() );
144 // this will build a SUIT_DataObject-s tree under myRoot member field
145 // passing "false" in order NOT to rebuild existing data models' trees - it was done in previous step
146 // but tree that corresponds to not-loaded data models will be updated any way.
147 ((SalomeApp_Application*)application())->updateObjectBrowser( false );
149 bool res = CAM_Study::openDocument( theStudyName );
152 //SRN: BugID IPAL9021: End
157 //=======================================================================
158 // name : saveDocumentAs
159 /*! Purpose : Save document*/
160 //=======================================================================
161 bool SalomeApp_Study::saveDocumentAs( const QString& theFileName )
163 ModelList list; dataModels( list );
165 SalomeApp_DataModel* aModel = (SalomeApp_DataModel*)list.first();
166 QStringList listOfFiles;
167 for ( ; aModel; aModel = (SalomeApp_DataModel*)list.next() ) {
169 aModel->saveAs( theFileName, this, listOfFiles );
170 if ( !listOfFiles.isEmpty() )
171 saveModuleData(aModel->module()->name(), listOfFiles);
174 // save SALOMEDS document
175 SUIT_ResourceMgr* resMgr = application()->resourceMgr();
179 bool isMultiFile = resMgr->booleanValue( "Study", "multi_file", false ),
180 isAscii = resMgr->booleanValue( "Study", "ascii_file", true );
181 isAscii ? SalomeApp_Application::studyMgr()->SaveAsASCII( theFileName.latin1(), studyDS(), isMultiFile ) :
182 SalomeApp_Application::studyMgr()->SaveAs ( theFileName.latin1(), studyDS(), isMultiFile );
184 bool res = CAM_Study::saveDocumentAs( theFileName ); //SRN: BugID IPAL9377, removed usage of uninitialized variable <res>
185 res = res && saveStudyData(theFileName);
192 //=======================================================================
193 // name : saveDocument
194 /*! Purpose : Save document*/
195 //=======================================================================
196 bool SalomeApp_Study::saveDocument()
198 ModelList list; dataModels( list );
200 SalomeApp_DataModel* aModel = (SalomeApp_DataModel*)list.first();
201 QStringList listOfFiles;
202 for ( ; aModel; aModel = (SalomeApp_DataModel*)list.next() ) {
204 aModel->save(listOfFiles);
205 if ( !listOfFiles.isEmpty() )
206 saveModuleData(aModel->module()->name(), listOfFiles);
209 // save SALOMEDS document
210 SUIT_ResourceMgr* resMgr = application()->resourceMgr();
214 bool isMultiFile = resMgr->booleanValue( "Study", "multi_file", false ),
215 isAscii = resMgr->booleanValue( "Study", "ascii_file", true );
216 isAscii ? SalomeApp_Application::studyMgr()->SaveASCII( studyDS(), isMultiFile ) :
217 SalomeApp_Application::studyMgr()->Save ( studyDS(), isMultiFile );
219 bool res = CAM_Study::saveDocument();
221 res = res && saveStudyData(studyName());
228 //================================================================
229 // Function : closeDocument
230 /*! Purpose : Close document*/
231 //================================================================
232 void SalomeApp_Study::closeDocument(bool permanently)
234 LightApp_Study::closeDocument(permanently);
236 // close SALOMEDS document
237 _PTR(Study) studyPtr = studyDS();
240 if(permanently) SalomeApp_Application::studyMgr()->Close( studyPtr );
241 SALOMEDSClient_Study* aStudy = 0;
242 setStudyDS( _PTR(Study)(aStudy) );
246 //================================================================
247 // Function : isModified
249 //================================================================
250 bool SalomeApp_Study::isModified() const
252 bool isAnyChanged = studyDS() && studyDS()->IsModified();
254 isAnyChanged = LightApp_Study::isModified();
259 //================================================================
260 // Function : isSaved
261 /*! Purpose : Check: data model is saved?*/
262 //================================================================
263 bool SalomeApp_Study::isSaved() const
265 bool isAllSaved = studyDS() && studyDS()->GetPersistentReference().size();
267 isAllSaved = LightApp_Study::isModified();
272 //=======================================================================
273 // name : saveModuleData
274 /*! Purpose : save list file for module 'theModuleName' */
275 //=======================================================================
276 void SalomeApp_Study::saveModuleData( QString theModuleName, QStringList theListOfFiles )
278 int aNb = theListOfFiles.count();
282 std::vector<std::string> aListOfFiles ( aNb );
284 for ( QStringList::Iterator it = theListOfFiles.begin(); it != theListOfFiles.end(); ++it ) {
285 if ( (*it).isEmpty() )
287 aListOfFiles[anIndex] = (*it).latin1();
290 SetListOfFiles(theModuleName, aListOfFiles);
293 //=======================================================================
294 // name : openModuleData
295 /*! Purpose : gets list of file for module 'theModuleNam' */
296 //=======================================================================
297 void SalomeApp_Study::openModuleData( QString theModuleName, QStringList& theListOfFiles )
299 std::vector<std::string> aListOfFiles = GetListOfFiles( theModuleName );
301 int i, aLength = aListOfFiles.size() - 1;
305 //Get a temporary directory for saved a file
306 theListOfFiles.append(aListOfFiles[0].c_str());
308 for(i = 0; i < aLength; i++)
309 theListOfFiles.append(aListOfFiles[i+1].c_str());
312 //=======================================================================
313 // name : saveStudyData
314 /*! Purpose : save data from study */
315 //=======================================================================
316 bool SalomeApp_Study::saveStudyData( const QString& theFileName )
318 ModelList list; dataModels( list );
319 SalomeApp_DataModel* aModel = (SalomeApp_DataModel*)list.first();
320 std::vector<std::string> listOfFiles(0);
321 for ( ; aModel; aModel = (SalomeApp_DataModel*)list.next() )
322 SetListOfFiles(aModel->module()->name(), listOfFiles);
326 //=======================================================================
327 // name : openStudyData
328 /*! Purpose : open data for study */
329 //=======================================================================
330 bool SalomeApp_Study::openStudyData( const QString& theFileName )
338 void SalomeApp_Study::setStudyDS( const _PTR(Study)& s )
346 void SalomeApp_Study::dataModelInserted (const CAM_DataModel* dm)
348 MESSAGE("SalomeApp_Study::dataModelInserted() : module name() = " << dm->module()->name());
350 CAM_Study::dataModelInserted(dm);
356 Create SComponent for module, using default engine (CORBAless)
358 void SalomeApp_Study::addComponent(const CAM_DataModel* dm)
360 SalomeApp_Module* aModule = dynamic_cast<SalomeApp_Module*>( dm->module() );
361 // 1. aModule == 0 means that this is a light module (no CORBA enigine)
363 // Check SComponent existance
364 _PTR(Study) aStudy = studyDS();
367 _PTR(SComponent) aComp = aStudy->FindComponent(dm->module()->name());
370 _PTR(StudyBuilder) aBuilder = aStudy->NewBuilder();
371 aComp = aBuilder->NewComponent(dm->module()->name());
372 aBuilder->SetName(aComp, dm->module()->moduleName().latin1());
373 QString anIconName = dm->module()->iconName();
374 if (!anIconName.isEmpty()) {
375 _PTR(AttributePixMap) anAttr = aBuilder->FindOrCreateAttribute(aComp, "AttributePixMap");
377 anAttr->SetPixMap(anIconName.latin1());
379 // Set default engine IOR
380 aBuilder->DefineComponentInstance(aComp, SalomeApp_Application::defaultEngineIOR().latin1());
381 SalomeApp_DataModel::BuildTree( aComp, root(), this, /*skipExisitng=*/true );
389 bool SalomeApp_Study::openDataModel( const QString& studyName, CAM_DataModel* dm )
394 // SalomeApp_DataModel* aDM = (SalomeApp_DataModel*)(dm);
395 SalomeApp_Module* aModule = dynamic_cast<SalomeApp_Module*>( dm->module() );
396 _PTR(Study) aStudy = studyDS(); // shared_ptr cannot be used here
397 _PTR(SComponent) aSComp;
399 // 1. aModule == 0 means that this is a light module (no CORBA enigine)
401 anEngine = SalomeApp_Application::defaultEngineIOR();
402 aSComp = aStudy->FindComponent(dm->module()->name());
405 SalomeApp_DataModel* aDM = dynamic_cast<SalomeApp_DataModel*>( dm );
407 QString anId = aDM->getRootEntry( this );
408 if ( anId.isEmpty() )
409 return true; // Probably nothing to load
410 anEngine = aDM->getModule()->engineIOR();
411 if ( anEngine.isEmpty() )
413 aSComp = aStudy->FindComponentID( std::string( anId.latin1() ) );
417 _PTR(StudyBuilder) aBuilder( aStudy->NewBuilder() );
420 aBuilder->LoadWith( aSComp, std::string( anEngine.latin1() ) );
422 catch( const SALOME::SALOME_Exception& ) {
423 // Oops, something went wrong while loading -> return an error
426 // Something has been read -> create data model tree
427 //SalomeApp_DataModel* aDM = dynamic_cast<SalomeApp_DataModel*>( dm );
428 // aDM->buildTree( aSComp, 0, this );
431 // Don't return false here, for there might be no data
432 // for a given component in the study yet
434 QStringList listOfFiles;
435 openModuleData(dm->module()->name(), listOfFiles);
436 if (dm && dm->open(studyName, this, listOfFiles)) {
437 // Remove the files and temporary directory, created
438 // for this module by LightApp_Engine_i::Load()
439 bool isMultiFile = false; // TODO: decide, how to access this parameter
440 RemoveTemporaryFiles( dm->module()->name(), isMultiFile );
442 // Something has been read -> create data model tree
443 LightApp_DataModel* aDM = dynamic_cast<LightApp_DataModel*>( dm );
445 aDM->update(NULL, this);
452 Create new study name.
454 QString SalomeApp_Study::newStudyName() const
456 std::vector<std::string> studies = SalomeApp_Application::studyMgr()->GetOpenStudies();
457 QString prefix( "Study%1" ), newName, curName;
458 int i = 1, j, n = studies.size();
459 while ( newName.isEmpty() ){
460 curName = prefix.arg( i );
461 for ( j = 0 ; j < n; j++ ){
462 if ( !strcmp( studies[j].c_str(), curName.latin1() ) )
473 //================================================================
474 // Function : GetListOfFiles
475 /*! Purpose : to be used by CORBAless modules*/
476 //================================================================
477 std::vector<std::string> SalomeApp_Study::GetListOfFiles( const char* theModuleName ) const
479 SalomeApp_Engine_i* aDefaultEngine = SalomeApp_Engine_i::GetInstance();
481 return aDefaultEngine->GetListOfFiles(id(), theModuleName);
483 std::vector<std::string> aListOfFiles;
487 //================================================================
488 // Function : SetListOfFiles
489 /*! Purpose : to be used by CORBAless modules*/
490 //================================================================
491 void SalomeApp_Study::SetListOfFiles ( const char* theModuleName,
492 const std::vector<std::string> theListOfFiles )
494 SalomeApp_Engine_i* aDefaultEngine = SalomeApp_Engine_i::GetInstance();
496 aDefaultEngine->SetListOfFiles(theListOfFiles, id(), theModuleName);
499 //================================================================
500 // Function : GetTmpDir
501 /*! Purpose : to be used by CORBAless modules*/
502 //================================================================
503 std::string SalomeApp_Study::GetTmpDir ( const char* theURL, const bool isMultiFile )
505 std::string anURLDir = SALOMEDS_Tool::GetDirFromPath(theURL);
506 std::string aTmpDir = isMultiFile ? anURLDir : SALOMEDS_Tool::GetTmpDir();
510 //================================================================
511 // Function : RemoveTemporaryFiles
512 /*! Purpose : to be used by CORBAless modules*/
513 //================================================================
514 void SalomeApp_Study::RemoveTemporaryFiles ( const char* theModuleName, const bool isMultiFile ) const
519 std::vector<std::string> aListOfFiles = GetListOfFiles( theModuleName );
520 if (aListOfFiles.size() > 0) {
521 std::string aTmpDir = aListOfFiles[0];
523 const int n = aListOfFiles.size() - 1;
524 SALOMEDS::ListOfFileNames_var aSeq = new SALOMEDS::ListOfFileNames;
526 for (int i = 0; i < n; i++)
527 aSeq[i] = CORBA::string_dup(aListOfFiles[i + 1].c_str());
529 SALOMEDS_Tool::RemoveTemporaryFiles(aTmpDir.c_str(), aSeq.in(), true);
533 // END: methods to be used by CORBAless modules
535 void SalomeApp_Study::deleteReferencesTo( _PTR( SObject ) obj )
537 _PTR(StudyBuilder) sb = studyDS()->NewBuilder();
538 std::vector<_PTR(SObject)> aRefs = studyDS()->FindDependances( obj );
539 for( int i=0, n=aRefs.size(); i<n; i++ )
541 _PTR( SObject ) o = aRefs[i];
542 if( o->GetFatherComponent()->ComponentDataType()==obj->GetFatherComponent()->ComponentDataType() )
544 sb->RemoveReference( o );
545 sb->RemoveObjectWithChildren( o );
550 //================================================================
551 // Function : referencedToEntry
552 /*! Purpose : Return referenced entry from entry*/
553 //================================================================
554 QString SalomeApp_Study::referencedToEntry( const QString& entry ) const
556 _PTR(SObject) obj = studyDS()->FindObjectID( entry.latin1() );
557 _PTR(SObject) refobj;
559 if( obj && obj->ReferencedObject( refobj ) )
560 return refobj->GetID().c_str();
561 return LightApp_Study::referencedToEntry( entry );
564 //================================================================
565 // Function : componentDataType
566 /*! Purpose : Return component data type from entry*/
567 //================================================================
568 QString SalomeApp_Study::componentDataType( const QString& entry ) const
570 _PTR(SObject) obj( studyDS()->FindObjectID( entry.latin1() ) );
572 return LightApp_Study::componentDataType( entry );
573 return obj->GetFatherComponent()->ComponentDataType().c_str();
576 //================================================================
577 // Function : componentDataType
578 /*! Purpose : Return component data type from entry*/
579 //================================================================
580 bool SalomeApp_Study::isComponent( const QString& entry ) const
582 _PTR(SObject) obj( studyDS()->FindObjectID( entry.latin1() ) );
583 return obj && QString( obj->GetID().c_str() ) == obj->GetFatherComponent()->GetID().c_str();
586 //================================================================
587 // Function : children
588 /*! Purpose : Return entries of children of object*/
589 //================================================================
590 void SalomeApp_Study::children( const QString& entry, QStringList& child_entries ) const
592 _PTR(SObject) SO = studyDS()->FindObjectID( entry.latin1() );
593 _PTR(ChildIterator) anIter ( studyDS()->NewChildIterator( SO ) );
594 anIter->InitEx( true );
595 while( anIter->More() )
597 _PTR(SObject) val( anIter->Value() );
598 child_entries.append( val->GetID() );
602 void SalomeApp_Study::components( QStringList& comps ) const
604 for( _PTR(SComponentIterator) it ( studyDS()->NewComponentIterator() ); it->More(); it->Next() )
606 _PTR(SComponent) aComponent ( it->Value() );
607 if( aComponent && aComponent->ComponentDataType() == "Interface Applicative" )
608 continue; // skip the magic "Interface Applicative" component
609 comps.append( aComponent->ComponentDataType() );