1 // Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
8 // This library is distributed in the hope that it will be useful
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // File: SalomeApp_DataModel.cxx
20 // Created: 10/25/2004 10:36:06 AM
21 // Author: Sergey LITONIN
22 // Copyright (C) CEA 2004
24 #include "SalomeApp_DataModel.h"
25 #include "SalomeApp_Study.h"
26 #include "SalomeApp_DataObject.h"
27 #include "SalomeApp_Module.h"
28 #include "SalomeApp_Application.h"
29 #include "SalomeApp_Engine_i.hxx"
31 #include "LightApp_RootObject.h"
33 #include <CAM_DataObject.h>
35 #include <SUIT_Application.h>
36 #include <SUIT_ResourceMgr.h>
37 #include <SUIT_Session.h>
38 #include <SUIT_TreeSync.h>
39 #include <SUIT_DataObjectIterator.h>
41 #include "SALOMEDS_Tool.hxx"
43 #include <SALOMEconfig.h>
44 #include CORBA_SERVER_HEADER(SALOME_Exception)
46 typedef _PTR(SObject) kerPtr;
47 typedef SUIT_DataObject* suitPtr;
50 \class SalomeApp_DataModelSync
51 Auxiliary class for synchronizing tree of kernel objects and SUIT_DataObjects
53 class SalomeApp_DataModelSync
56 SalomeApp_DataModelSync( _PTR( Study ), SUIT_DataObject* );
58 suitPtr createItem( const kerPtr&, const suitPtr&, const suitPtr&, const bool ) const;
59 void deleteItemWithChildren( const suitPtr& ) const;
60 bool isEqual( const kerPtr&, const suitPtr& ) const;
61 kerPtr nullSrc() const;
62 suitPtr nullTrg() const;
63 void children( const kerPtr&, QValueList<kerPtr>& ) const;
64 void children( const suitPtr&, QValueList<suitPtr>& ) const;
65 suitPtr parent( const suitPtr& ) const;
66 bool isCorrect( const kerPtr& ) const;
67 void updateItem( const suitPtr& ) const;
70 _PTR( Study ) myStudy;
71 SUIT_DataObject* myRoot;
77 SalomeApp_DataModelSync::SalomeApp_DataModelSync( _PTR( Study ) aStudy, SUIT_DataObject* aRoot )
84 \return true if kernel object is correct (has non empty name or is reference)
86 bool SalomeApp_DataModelSync::isCorrect( const kerPtr& so ) const
89 QString name = so->GetName().c_str();
90 bool res = so && ( so->GetName().size() || so->ReferencedObject( refObj ) );
95 Creates SUIT object by KERNEL object
96 \param so - corresponding KERNEL object
97 \param parent - parent for SUIT object
98 \param after - previous sibling for SUIT object
99 \param prepend - SUIT object must be added to start of children list
101 suitPtr SalomeApp_DataModelSync::createItem( const kerPtr& so,
102 const suitPtr& parent,
103 const suitPtr& after,
104 const bool prepend ) const
106 if( !isCorrect( so ) )
109 _PTR(SComponent) aSComp( so );
110 suitPtr nitem = aSComp ? new SalomeApp_ModuleObject( aSComp, 0 ) :
111 new SalomeApp_DataObject( so, 0 );
116 parent->children( ch );
117 int pos = ch.find( after );
119 parent->insertChild( nitem, pos+1 );
121 parent->appendChild( nitem );
124 parent->insertChild( nitem, 0 );
126 parent->appendChild( nitem );
128 myRoot->appendChild( nitem );
133 Deletes object with all children
134 \param p - SUIT object
136 void SalomeApp_DataModelSync::deleteItemWithChildren( const suitPtr& p ) const
143 DataObjectList::const_iterator anIt = ch.begin(), aLast = ch.end();
144 for( ; anIt!=aLast; anIt++ )
145 deleteItemWithChildren( *anIt );
150 \return true if objects correspond each other at all
151 \param p - kernel object
152 \param q - suit object
154 bool SalomeApp_DataModelSync::isEqual( const kerPtr& p, const suitPtr& q ) const
156 LightApp_ModuleObject* lobj = dynamic_cast<LightApp_ModuleObject*>( q );
157 SalomeApp_DataObject* sobj = dynamic_cast<SalomeApp_DataObject*>( q );
158 _PTR( SComponent ) aComp( p );
159 bool res = ( !p && !q ) ||
160 ( lobj && !sobj && aComp ) ||
161 ( sobj && isCorrect( p ) && p->GetID().c_str()==sobj->entry() );
166 \return null kernel object
168 kerPtr SalomeApp_DataModelSync::nullSrc() const
174 \return null suit object
176 suitPtr SalomeApp_DataModelSync::nullTrg() const
182 Fills list with children of kernel object
183 \param obj - kernel object
184 \param ch - list to be filled
186 void SalomeApp_DataModelSync::children( const kerPtr& obj, QValueList<kerPtr>& ch ) const
189 _PTR(ChildIterator) it ( myStudy->NewChildIterator( obj ) );
190 for( ; it->More(); it->Next() )
191 ch.append( it->Value() );
195 Fills list with children of SUIT object
196 \param p - SUIT object
197 \param ch - list to be filled
199 void SalomeApp_DataModelSync::children( const suitPtr& p, QValueList<suitPtr>& ch ) const
206 for( SUIT_DataObject* o = l.first(); o; o = l.next() )
212 \return parent of SUIT object
213 \param p - SUIT object
215 suitPtr SalomeApp_DataModelSync::parent( const suitPtr& p ) const
217 return p ? p->parent(): 0;
222 \param p - SUIT object
224 void SalomeApp_DataModelSync::updateItem( const suitPtr& ) const
229 Auxiliary function, shows SUIT tree
231 void showTree( SUIT_DataObject* root )
233 qDebug( root ? "<tree>" : "<empty tree>" );
237 SUIT_DataObjectIterator it( root, SUIT_DataObjectIterator::DepthLeft );
238 for( ; it.current(); ++it )
240 QString marg; marg.fill( ' ', 3*it.depth() );
241 QString nnn = "%1 '%2'";
242 qDebug( nnn.arg( marg ).arg( it.current()->name() ) );
249 SalomeApp_DataModel::SalomeApp_DataModel( CAM_Module* theModule )
250 : LightApp_DataModel( theModule )
257 SalomeApp_DataModel::~SalomeApp_DataModel()
264 bool SalomeApp_DataModel::open( const QString& name, CAM_Study* study, QStringList )
266 SalomeApp_Study* aDoc = dynamic_cast<SalomeApp_Study*>( study );
270 QString anId = getRootEntry( aDoc );
271 if ( anId.isEmpty() )
272 return true; // Probably nothing to load
274 _PTR(Study) aStudy ( aDoc->studyDS() ); // shared_ptr cannot be used here
275 _PTR(SComponent) aSComp ( aStudy->FindComponentID( std::string( anId.latin1() ) ) );
277 updateTree( aSComp, aDoc );
279 QStringList listOfFiles;
280 LightApp_DataModel::open(name, study, listOfFiles);
287 bool SalomeApp_DataModel::create( CAM_Study* theStudy )
289 update(NULL, (LightApp_Study*)theStudy);
296 void SalomeApp_DataModel::update( LightApp_DataObject*, LightApp_Study* study )
298 SalomeApp_Study* aSStudy = dynamic_cast<SalomeApp_Study*>(study);
299 LightApp_RootObject* studyRoot = 0;
300 _PTR(SComponent) sobj;
301 SalomeApp_DataObject* modelRoot = dynamic_cast<SalomeApp_DataObject*>( root() );
302 if ( !modelRoot ){ // not yet connected to a study -> try using <study> argument
304 aSStudy = dynamic_cast<SalomeApp_Study*>( getModule()->getApp()->activeStudy() );
306 studyRoot = dynamic_cast<LightApp_RootObject*>( aSStudy->root() );
307 QString anId = getRootEntry( aSStudy );
308 if ( !anId.isEmpty() ){ // if nothing is published in the study for this module -> do nothing
309 _PTR(Study) aStudy ( aSStudy->studyDS() );
310 sobj = aStudy->FindComponentID( std::string( anId.latin1() ) );
315 studyRoot = dynamic_cast<LightApp_RootObject*>( modelRoot->root() );
317 aSStudy = dynamic_cast<SalomeApp_Study*>( studyRoot->study() ); // <study> value should not change here theoretically, but just to make sure
319 _PTR(Study) aStudy ( aSStudy->studyDS() );
320 // modelRoot->object() cannot be reused here: it is about to be deleted by buildTree() soon
321 sobj = aStudy->FindComponentID( std::string( modelRoot->entry().latin1() ) );
325 if ( sobj && aSStudy )
326 updateTree( sobj, aSStudy );
330 Synchronizes kernel tree and suit data tree starting from component 'sobj'
332 SUIT_DataObject* SalomeApp_DataModel::synchronize( const _PTR( SComponent )& sobj, SalomeApp_Study* study )
334 if( !study || !study->root() || !sobj )
337 DataObjectList ch; study->root()->children( ch );
338 DataObjectList::const_iterator anIt = ch.begin(), aLast = ch.end();
339 SUIT_DataObject* suitObj = 0;
340 for( ; anIt!=aLast; anIt++ )
342 LightApp_DataObject* dobj = dynamic_cast<LightApp_DataObject*>( *anIt );
343 if( dobj && dobj->name() == sobj->GetName().c_str() )
350 SalomeApp_DataModelSync sync( study->studyDS(), study->root() );
352 if( !suitObj || dynamic_cast<SalomeApp_DataObject*>( suitObj ) )
353 return ::synchronize<kerPtr,suitPtr,SalomeApp_DataModelSync>( sobj, suitObj, sync );
361 void SalomeApp_DataModel::updateTree( const _PTR( SComponent )& comp, SalomeApp_Study* study )
363 SalomeApp_ModuleObject* aNewRoot = dynamic_cast<SalomeApp_ModuleObject*>( synchronize( comp, study ) );
366 aNewRoot->setDataModel( this );
374 SalomeApp_Module* SalomeApp_DataModel::getModule() const
376 return dynamic_cast<SalomeApp_Module*>( module() );
382 SalomeApp_Study* SalomeApp_DataModel::getStudy() const
384 if(!root()) return 0;
385 LightApp_RootObject* aRoot = dynamic_cast<LightApp_RootObject*>( root()->root() );
388 SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( aRoot->study() );
395 \return study entry corresponding to this data model
397 QString SalomeApp_DataModel::getRootEntry( SalomeApp_Study* study ) const
400 if ( root() && root()->root() ) { // data model already in a study
401 SalomeApp_DataObject* anObj = dynamic_cast<SalomeApp_DataObject*>( root() );
403 anEntry = anObj->entry();
405 else if ( study && study->studyDS() ) { // this works even if <myRoot> is null
406 _PTR(SComponent) aSComp( study->studyDS()->FindComponent( module()->name() ) );
408 anEntry = aSComp->GetID().c_str();