1 // File: SalomeApp_DataModel.cxx
2 // Created: 10/25/2004 10:36:06 AM
3 // Author: Sergey LITONIN
4 // Copyright (C) CEA 2004
6 #include "SalomeApp_DataModel.h"
7 #include "SalomeApp_Study.h"
8 #include "SalomeApp_RootObject.h"
9 #include "SalomeApp_DataObject.h"
10 #include "SalomeApp_Module.h"
11 #include "SalomeApp_Application.h"
12 #include "SalomeApp_SelectionMgr.h"
13 #include "SalomeApp_Engine_i.hxx"
15 #include <CAM_DataObject.h>
17 #include <SUIT_Application.h>
18 #include <SUIT_ResourceMgr.h>
19 #include <SUIT_Session.h>
21 #include "SALOMEDS_Tool.hxx"
23 #include <SALOMEconfig.h>
24 #include CORBA_SERVER_HEADER(SALOME_Exception)
26 //=======================================================================
28 /*!Purpose : static method used by SalomeApp_Study and SalomeApp_DataModel classes
29 * to create default SALOMEDS-based data object tree
31 //=======================================================================
32 SUIT_DataObject* SalomeApp_DataModel::BuildTree( const _PTR(SObject)& obj,
33 SUIT_DataObject* parent,
34 SalomeApp_Study* study,
37 SalomeApp_DataObject* aDataObj = 0;
42 if ( obj->GetName().size() || obj->ReferencedObject( refObj ) ) // skip nameless non references SObjects
44 _PTR(SComponent) aSComp( obj );
46 // patch for bug IPAL9313
47 if ( aSComp && parent && skip )
49 QString aSName( aSComp->GetName().c_str() );
50 DataObjectList allComponents = parent->children( /*recursive=*/false );
51 for ( DataObjectListIterator it( allComponents ); it.current(); ++it ) {
52 SUIT_DataObject* componentObj = it.current();
53 if ( componentObj->name() == aSName ) {
54 // mkr : modifications for update of already published in
55 // object browser, but not loaded yet components
56 CAM_Application* anApp = dynamic_cast<CAM_Application*>
57 (SUIT_Session::session()->activeApplication());
59 // asv : corresponding DataObjects are DELETED before update (so they are re-built).
60 if (anApp && !anApp->module(aSName)) { // if module is not loaded, delete it's DataObject
61 // jfa: remove children before DataObject deletion
62 DataObjectList chilren = componentObj->children(/*recursive=*/true);
63 for (DataObjectListIterator itc (chilren); itc.current(); ++itc)
64 componentObj->removeChild(itc.current());
66 // delete DataObject itself and re-create it and all its sub-objects
68 // don't do anything here, because iterator may be corrupted (deleted object inside it)
69 break; // proceed to build_a_data_object code below
77 aDataObj = aSComp ? new SalomeApp_ModuleObject( aSComp, parent ) :
78 new SalomeApp_DataObject ( obj, parent );
80 _PTR(ChildIterator) it ( study->studyDS()->NewChildIterator( obj ) );
81 for ( ; it->More(); it->Next() ) {
82 // don't use shared_ptr here, for Data Object will take
83 // ownership of this pointer
84 _PTR(SObject) aSO( it->Value() );
85 BuildTree( aSO, aDataObj, study );
91 //=======================================================================
92 // name : SalomeApp_DataModel::SalomeApp_DataModel
93 /*!Purpose : Constructor*/
94 //=======================================================================
95 SalomeApp_DataModel::SalomeApp_DataModel( CAM_Module* theModule )
96 : CAM_DataModel( theModule )
100 //=======================================================================
101 // name : SalomeApp_DataModel::~SalomeApp_DataModel
102 /*! Purpose : Destructor*/
103 //=======================================================================
104 SalomeApp_DataModel::~SalomeApp_DataModel()
108 //================================================================
110 /*! Purpose : Open data model*/
111 //================================================================
112 bool SalomeApp_DataModel::open( const QString&, CAM_Study* study )
114 SalomeApp_Study* aDoc = dynamic_cast<SalomeApp_Study*>( study );
118 QString anId = getRootEntry( aDoc );
119 if ( anId.isEmpty() )
120 return true; // Probably nothing to load
122 QString anEngine = getModule()->engineIOR();
123 if ( anEngine == "-1" ) {
124 // Module doesn't have a CORBA engine and doesn't use
125 // a default one -> SALOMEDS persistence cannot be used
129 if ( anEngine.isEmpty() ) {
130 // Module use a default engine
131 //TODO: deside, if the below code has to be copyed in a light data model to avoid bulding of data tree twice
132 anEngine = SalomeApp_Application::defaultEngineIOR();
135 _PTR(Study) aStudy ( aDoc->studyDS() ); // shared_ptr cannot be used here
136 _PTR(SComponent) aSComp ( aStudy->FindComponentID( std::string( anId.latin1() ) ) );
139 _PTR(StudyBuilder) aBuilder( aStudy->NewBuilder() );
142 aBuilder->LoadWith( aSComp, std::string( anEngine.latin1() ) );
144 catch( const SALOME::SALOME_Exception& ) {
145 // Oops, something went wrong while loading -> return an error
149 // Something has been read -> create data model tree
150 buildTree( aSComp, 0, aDoc );
153 // Don't return false here, for there might be no data
154 // for a given component in the study yet
157 emit opened(); //TODO: is it really needed? to be removed maybe...
161 //================================================================
163 /*! Purpose : Emit saved()*/
164 //================================================================
165 bool SalomeApp_DataModel::save()
171 //================================================================
173 /*! Purpose : Emit saved() */
174 //================================================================
175 bool SalomeApp_DataModel::saveAs( const QString&, CAM_Study* )
181 //================================================================
183 /*! Purpose : Emit closed()*/
184 //================================================================
185 bool SalomeApp_DataModel::close()
191 //================================================================
193 /*! Purpose : Update application.*/
194 //================================================================
195 void SalomeApp_DataModel::update( SalomeApp_DataObject*, SalomeApp_Study* study )
197 SalomeApp_RootObject* studyRoot = 0;
199 SalomeApp_DataObject* modelRoot = dynamic_cast<SalomeApp_DataObject*>( root() );
200 if ( !modelRoot ){ // not yet connected to a study -> try using <study> argument
202 study = dynamic_cast<SalomeApp_Study*>( getModule()->getApp()->activeStudy() );
205 studyRoot = dynamic_cast<SalomeApp_RootObject*>( study->root() );
206 QString anId = getRootEntry( study );
207 if ( !anId.isEmpty() ){ // if nothing is published in the study for this module -> do nothing
208 _PTR(Study) aStudy ( study->studyDS() );
209 sobj = aStudy->FindComponentID( std::string( anId.latin1() ) );
214 studyRoot = dynamic_cast<SalomeApp_RootObject*>( modelRoot->root() );
215 study = studyRoot->study(); // <study> value should not change here theoretically, but just to make sure
216 _PTR(Study) aStudy ( study->studyDS() );
218 // modelRoot->object() cannot be reused here: it is about to be deleted by buildTree() soon
219 sobj = aStudy->FindComponentID( std::string( modelRoot->entry().latin1() ) );
221 buildTree( sobj, studyRoot, study );
224 //================================================================
225 // Function : buildTree
226 /*! Purpose : private method, build tree.*/
227 //================================================================
228 void SalomeApp_DataModel::buildTree( const _PTR(SObject)& obj,
229 SUIT_DataObject* parent,
230 SalomeApp_Study* study )
234 //if ( !root() ){ // Build default SALOMEDS-based data object tree and insert it into study
235 SalomeApp_ModuleObject* aNewRoot = dynamic_cast<SalomeApp_ModuleObject*>( BuildTree( obj, parent, study ) );
237 aNewRoot->setDataModel( this );
243 //================================================================
244 // Function : getModule
245 /*! Purpose : gets module*/
246 //================================================================
248 SalomeApp_Module* SalomeApp_DataModel::getModule() const
250 return dynamic_cast<SalomeApp_Module*>( module() );
253 //================================================================
254 // Function : getStudy
255 /*! Purpose : gets study */
256 //================================================================
257 SalomeApp_Study* SalomeApp_DataModel::getStudy() const
259 if(!root()) return 0;
260 SalomeApp_RootObject* aRoot = dynamic_cast<SalomeApp_RootObject*>( root()->root() );
263 return aRoot->study();
266 //================================================================
267 // Function : getRootEntry
268 /*! Purpose : returns study entry corresponding to this data model*/
269 //================================================================
270 QString SalomeApp_DataModel::getRootEntry( SalomeApp_Study* study ) const
273 if ( root() && root()->root() ) { // data model already in a study
274 SalomeApp_DataObject* anObj = dynamic_cast<SalomeApp_DataObject*>( root() );
276 anEntry = anObj->entry();
278 else if ( study && study->studyDS() ) { // this works even if <myRoot> is null
279 _PTR(SComponent) aSComp( study->studyDS()->FindComponent( module()->name() ) );
281 anEntry = aSComp->GetID().c_str();
286 //================================================================
287 // Function : isModified
288 /*! Purpose : default implementation, always returns false so as not to mask study's isModified()*/
289 //================================================================
290 bool SalomeApp_DataModel::isModified() const
295 //================================================================
296 // Function : isSaved
297 /*! Purpose : default implementation, always returns true so as not to mask study's isSaved()*/
298 //================================================================
299 bool SalomeApp_DataModel::isSaved() const
304 // BEGIN: methods to be used by CORBAless modules
306 //================================================================
307 // Function : GetListOfFiles
308 /*! Purpose : to be used by CORBAless modules*/
309 //================================================================
310 std::vector<std::string> SalomeApp_DataModel::GetListOfFiles() const
311 //(const int theStudyId, const char* theComponentName) const
313 SUIT_Study* anActiveStudy = getModule()->getApp()->activeStudy();
315 int aStudyId = anActiveStudy->id();
316 SalomeApp_Engine_i* aDefaultEngine = SalomeApp_Engine_i::GetInstance();
317 if (aDefaultEngine) {
318 return aDefaultEngine->GetListOfFiles(aStudyId, module()->name());
322 std::vector<std::string> aListOfFiles;
326 //================================================================
327 // Function : SetListOfFiles
328 /*! Purpose : to be used by CORBAless modules*/
329 //================================================================
330 void SalomeApp_DataModel::SetListOfFiles (const std::vector<std::string> theListOfFiles)
331 //(const std::vector<std::string> theListOfFiles,
332 // const int theStudyId,
333 // const char* theComponentName)
335 SUIT_Study* anActiveStudy = getModule()->getApp()->activeStudy();
337 int aStudyId = anActiveStudy->id();
338 SalomeApp_Engine_i* aDefaultEngine = SalomeApp_Engine_i::GetInstance();
339 if (aDefaultEngine) {
340 aDefaultEngine->SetListOfFiles(theListOfFiles, aStudyId, module()->name());
345 //================================================================
346 // Function : GetTmpDir
347 /*! Purpose : Static method. To be used by CORBAless modules*/
348 //================================================================
349 std::string SalomeApp_DataModel::GetTmpDir (const char* theURL,
350 const bool isMultiFile)
352 std::string anURLDir = SALOMEDS_Tool::GetDirFromPath(theURL);
353 std::string aTmpDir = isMultiFile ? anURLDir : SALOMEDS_Tool::GetTmpDir();
357 //================================================================
358 // Function : RemoveTemporaryFiles
359 /*! Purpose : to be used by CORBAless modules*/
360 //================================================================
361 void SalomeApp_DataModel::RemoveTemporaryFiles (const bool isMultiFile) const
366 std::vector<std::string> aListOfFiles = GetListOfFiles();
367 if (aListOfFiles.size() > 0) {
368 std::string aTmpDir = aListOfFiles[0];
370 const int n = aListOfFiles.size() - 1;
371 SALOMEDS::ListOfFileNames_var aSeq = new SALOMEDS::ListOfFileNames;
373 for (int i = 0; i < n; i++)
374 aSeq[i] = CORBA::string_dup(aListOfFiles[i + 1].c_str());
376 SALOMEDS_Tool::RemoveTemporaryFiles(aTmpDir.c_str(), aSeq.in(), true);
380 // END: methods to be used by CORBAless modules