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_DataObject.h"
9 #include "SalomeApp_Module.h"
10 #include "SalomeApp_Application.h"
11 #include "SalomeApp_Engine_i.hxx"
13 #include "LightApp_RootObject.h"
15 #include <CAM_DataObject.h>
17 #include <SUIT_Application.h>
18 #include <SUIT_ResourceMgr.h>
19 #include <SUIT_Session.h>
20 #include <SUIT_TreeSync.h>
21 #include <SUIT_DataObjectIterator.h>
23 #include "SALOMEDS_Tool.hxx"
25 #include <SALOMEconfig.h>
26 #include CORBA_SERVER_HEADER(SALOME_Exception)
28 //=======================================================================
29 // name : SalomeApp_DataModelSync
30 /*!Purpose : Auxiliary class for synchronizing tree of kernel objects and SUIT_DataObjects */
31 //=======================================================================
33 typedef _PTR(SObject) kerPtr;
34 typedef SUIT_DataObject* suitPtr;
36 class SalomeApp_DataModelSync
39 SalomeApp_DataModelSync( _PTR( Study ), SUIT_DataObject* );
41 suitPtr createItem( const kerPtr&, const suitPtr&, const suitPtr&, const bool ) const;
42 void deleteItemWithChildren( const suitPtr& ) const;
43 bool isEqual( const kerPtr&, const suitPtr& ) const;
44 kerPtr nullSrc() const;
45 suitPtr nullTrg() const;
46 void children( const kerPtr&, QValueList<kerPtr>& ) const;
47 void children( const suitPtr&, QValueList<suitPtr>& ) const;
48 suitPtr parent( const suitPtr& ) const;
49 bool isCorrect( const kerPtr& ) const;
50 void updateItem( const suitPtr& ) const;
53 _PTR( Study ) myStudy;
54 SUIT_DataObject* myRoot;
58 SalomeApp_DataModelSync::SalomeApp_DataModelSync( _PTR( Study ) aStudy, SUIT_DataObject* aRoot )
64 bool SalomeApp_DataModelSync::isCorrect( const kerPtr& so ) const
67 QString name = so->GetName().c_str();
68 bool res = so && ( so->GetName().size() || so->ReferencedObject( refObj ) );
72 suitPtr SalomeApp_DataModelSync::createItem( const kerPtr& so,
73 const suitPtr& parent,
75 const bool prepend ) const
77 if( !isCorrect( so ) )
80 _PTR(SComponent) aSComp( so );
81 suitPtr nitem = aSComp ? new SalomeApp_ModuleObject( aSComp, 0 ) :
82 new SalomeApp_DataObject( so, 0 );
87 parent->children( ch );
88 int pos = ch.find( after );
90 parent->insertChild( nitem, pos+1 );
92 parent->appendChild( nitem );
95 parent->insertChild( nitem, 0 );
97 parent->appendChild( nitem );
99 myRoot->appendChild( nitem );
103 void SalomeApp_DataModelSync::deleteItemWithChildren( const suitPtr& p ) const
110 DataObjectList::const_iterator anIt = ch.begin(), aLast = ch.end();
111 for( ; anIt!=aLast; anIt++ )
112 deleteItemWithChildren( *anIt );
116 bool SalomeApp_DataModelSync::isEqual( const kerPtr& p, const suitPtr& q ) const
118 LightApp_DataObject* obj = dynamic_cast<LightApp_DataObject*>( q );
119 return ( !p && !q ) || ( obj && isCorrect( p ) && p->GetID().c_str()==obj->entry() );
122 kerPtr SalomeApp_DataModelSync::nullSrc() const
127 suitPtr SalomeApp_DataModelSync::nullTrg() const
132 void SalomeApp_DataModelSync::children( const kerPtr& obj, QValueList<kerPtr>& ch ) const
135 _PTR(ChildIterator) it ( myStudy->NewChildIterator( obj ) );
136 for( ; it->More(); it->Next() )
137 ch.append( it->Value() );
140 void SalomeApp_DataModelSync::children( const suitPtr& p, QValueList<suitPtr>& ch ) const
147 for( SUIT_DataObject* o = l.first(); o; o = l.next() )
152 suitPtr SalomeApp_DataModelSync::parent( const suitPtr& p ) const
154 return p ? p->parent(): 0;
157 void SalomeApp_DataModelSync::updateItem( const suitPtr& ) const
161 void showTree( SUIT_DataObject* root )
163 qDebug( root ? "<tree>" : "<empty tree>" );
167 SUIT_DataObjectIterator it( root, SUIT_DataObjectIterator::DepthLeft );
168 for( ; it.current(); ++it )
170 QString marg; marg.fill( ' ', 3*it.depth() );
171 QString nnn = "%1 '%2'";
172 qDebug( nnn.arg( marg ).arg( it.current()->name() ) );
176 //=======================================================================
177 // name : SalomeApp_DataModel::SalomeApp_DataModel
178 /*!Purpose : Constructor*/
179 //=======================================================================
180 SalomeApp_DataModel::SalomeApp_DataModel( CAM_Module* theModule )
181 : LightApp_DataModel( theModule )
185 //=======================================================================
186 // name : SalomeApp_DataModel::~SalomeApp_DataModel
187 /*! Purpose : Destructor*/
188 //=======================================================================
189 SalomeApp_DataModel::~SalomeApp_DataModel()
193 //================================================================
195 /*! Purpose : Open data model*/
196 //================================================================
197 bool SalomeApp_DataModel::open( const QString& name, CAM_Study* study, QStringList )
199 SalomeApp_Study* aDoc = dynamic_cast<SalomeApp_Study*>( study );
203 QString anId = getRootEntry( aDoc );
204 if ( anId.isEmpty() )
205 return true; // Probably nothing to load
207 _PTR(Study) aStudy ( aDoc->studyDS() ); // shared_ptr cannot be used here
208 _PTR(SComponent) aSComp ( aStudy->FindComponentID( std::string( anId.latin1() ) ) );
210 updateTree( aSComp, aDoc );
212 QStringList listOfFiles;
213 LightApp_DataModel::open(name, study, listOfFiles);
217 //================================================================
219 /*! Purpose : Create data model*/
220 //================================================================
221 bool SalomeApp_DataModel::create( CAM_Study* theStudy )
223 update(NULL, (LightApp_Study*)theStudy);
227 //================================================================
229 /*! Purpose : Update application.*/
230 //================================================================
231 void SalomeApp_DataModel::update( LightApp_DataObject*, LightApp_Study* study )
233 SalomeApp_Study* aSStudy = dynamic_cast<SalomeApp_Study*>(study);
234 LightApp_RootObject* studyRoot = 0;
235 _PTR(SComponent) sobj;
236 SalomeApp_DataObject* modelRoot = dynamic_cast<SalomeApp_DataObject*>( root() );
237 if ( !modelRoot ){ // not yet connected to a study -> try using <study> argument
239 aSStudy = dynamic_cast<SalomeApp_Study*>( getModule()->getApp()->activeStudy() );
241 studyRoot = dynamic_cast<LightApp_RootObject*>( aSStudy->root() );
242 QString anId = getRootEntry( aSStudy );
243 if ( !anId.isEmpty() ){ // if nothing is published in the study for this module -> do nothing
244 _PTR(Study) aStudy ( aSStudy->studyDS() );
245 sobj = aStudy->FindComponentID( std::string( anId.latin1() ) );
250 studyRoot = dynamic_cast<LightApp_RootObject*>( modelRoot->root() );
252 aSStudy = dynamic_cast<SalomeApp_Study*>( studyRoot->study() ); // <study> value should not change here theoretically, but just to make sure
254 _PTR(Study) aStudy ( aSStudy->studyDS() );
255 // modelRoot->object() cannot be reused here: it is about to be deleted by buildTree() soon
256 sobj = aStudy->FindComponentID( std::string( modelRoot->entry().latin1() ) );
260 if ( sobj && aSStudy )
261 updateTree( sobj, aSStudy );
264 //================================================================
265 // Function : synchronize
266 /*! Purpose : synchronizes kernel tree and suit data tree starting from component 'sobj' */
267 //================================================================
268 SUIT_DataObject* SalomeApp_DataModel::synchronize( const _PTR( SComponent )& sobj, SalomeApp_Study* study )
270 if( !study || !study->root() || !sobj )
273 DataObjectList ch; study->root()->children( ch );
274 DataObjectList::const_iterator anIt = ch.begin(), aLast = ch.end();
275 SalomeApp_DataObject* suitObj = 0;
276 for( ; anIt!=aLast; anIt++ )
278 SalomeApp_DataObject* dobj = dynamic_cast<SalomeApp_DataObject*>( *anIt );
279 if( dobj && dobj->name()==sobj->GetName().c_str() )
286 SalomeApp_DataModelSync sync( study->studyDS(), study->root() );
288 return ::synchronize<kerPtr,suitPtr,SalomeApp_DataModelSync>( sobj, suitObj, sync );
291 //================================================================
292 // Function : updateTree
293 /*! Purpose : updates tree.*/
294 //================================================================
295 void SalomeApp_DataModel::updateTree( const _PTR( SComponent )& comp, SalomeApp_Study* study )
297 SalomeApp_ModuleObject* aNewRoot = dynamic_cast<SalomeApp_ModuleObject*>( synchronize( comp, study ) );
300 aNewRoot->setDataModel( this );
305 //================================================================
306 // Function : getModule
307 /*! Purpose : gets module*/
308 //================================================================
310 SalomeApp_Module* SalomeApp_DataModel::getModule() const
312 return dynamic_cast<SalomeApp_Module*>( module() );
315 //================================================================
316 // Function : getStudy
317 /*! Purpose : gets study */
318 //================================================================
319 SalomeApp_Study* SalomeApp_DataModel::getStudy() const
321 if(!root()) return 0;
322 LightApp_RootObject* aRoot = dynamic_cast<LightApp_RootObject*>( root()->root() );
325 SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( aRoot->study() );
331 //================================================================
332 // Function : getRootEntry
333 /*! Purpose : returns study entry corresponding to this data model*/
334 //================================================================
335 QString SalomeApp_DataModel::getRootEntry( SalomeApp_Study* study ) const
338 if ( root() && root()->root() ) { // data model already in a study
339 SalomeApp_DataObject* anObj = dynamic_cast<SalomeApp_DataObject*>( root() );
341 anEntry = anObj->entry();
343 else if ( study && study->studyDS() ) { // this works even if <myRoot> is null
344 _PTR(SComponent) aSComp( study->studyDS()->FindComponent( module()->name() ) );
346 anEntry = aSComp->GetID().c_str();