Back to index

salome-gui  6.5.0
SalomeApp_DataModel.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 // File:      SalomeApp_DataModel.cxx
00024 // Created:   10/25/2004 10:36:06 AM
00025 // Author:    Sergey LITONIN
00026 
00027 #include "SalomeApp_DataModel.h"
00028 #include "SalomeApp_Study.h"
00029 #include "SalomeApp_DataObject.h"
00030 #include "SalomeApp_Module.h"
00031 #include "SalomeApp_Application.h"
00032 
00033 #include <CAM_DataObject.h>
00034 
00035 #include <SUIT_TreeSync.h>
00036 #include <SUIT_DataObjectIterator.h>
00037 
00038 #include <SALOMEconfig.h>
00039 #include CORBA_SERVER_HEADER(SALOME_Exception)
00040 
00041 typedef _PTR(SObject)     kerPtr;
00042 typedef SUIT_DataObject*  suitPtr;
00043 
00048 class SalomeApp_DataModelSync
00049 {
00050 public:
00051   SalomeApp_DataModelSync( _PTR( Study ), SUIT_DataObject* );
00052 
00053   bool           isEqual( const kerPtr&, const suitPtr& ) const;
00054   kerPtr         nullSrc() const;
00055   suitPtr        nullTrg() const;
00056   suitPtr        createItem( const kerPtr&, const suitPtr&, const suitPtr& ) const;
00057   void           updateItem( const kerPtr&, const suitPtr& ) const;
00058   void           deleteItemWithChildren( const suitPtr& ) const;
00059   QList<kerPtr>  children( const kerPtr& ) const;
00060   QList<suitPtr> children( const suitPtr& ) const;
00061   suitPtr        parent( const suitPtr& ) const;
00062 
00063 private:
00064   bool           isCorrect( const kerPtr& ) const;
00065 
00066 private:
00067   _PTR( Study )     myStudy;
00068   SUIT_DataObject*  myRoot;
00069 };
00070 
00074 SalomeApp_DataModelSync::SalomeApp_DataModelSync( _PTR( Study ) aStudy, SUIT_DataObject* aRoot )
00075 : myStudy( aStudy ),
00076   myRoot( aRoot )
00077 {
00078 }
00079 
00083 bool SalomeApp_DataModelSync::isCorrect( const kerPtr& so ) const
00084 {
00085 #ifdef WITH_SALOMEDS_OBSERVER
00086   // with GUI observers this function is not needed anymore
00087   return true;
00088 #endif
00089   kerPtr refObj;
00090   QString name = so->GetName().c_str();
00091   _PTR( GenericAttribute ) anAttr;
00092   bool isDraw = true;
00093   if ( so->FindAttribute(anAttr, "AttributeDrawable") ) 
00094   {
00095     _PTR(AttributeDrawable) aAttrDraw = anAttr;
00096     isDraw = aAttrDraw->IsDrawable(); 
00097   }
00098   bool res = so && ( so->GetName().size() || so->ReferencedObject( refObj ) ) && isDraw;  
00099   return res;
00100 }
00101 
00109 suitPtr SalomeApp_DataModelSync::createItem( const kerPtr& so,
00110                                              const suitPtr& parent,
00111                                              const suitPtr& after ) const
00112 {
00113   if( !isCorrect( so ) )
00114     return 0;
00115 
00116   _PTR(SComponent) aSComp( so );
00117   suitPtr nitem = aSComp ? new SalomeApp_ModuleObject( aSComp, 0 ) :
00118                            new SalomeApp_DataObject( so, 0 );
00119 
00120   if( parent ) {
00121     int pos = after ? parent->childPos( after ) : 0;
00122     parent->insertChild( nitem, pos+1 );
00123   }
00124   else if( myRoot ) {
00125     myRoot->appendChild( nitem );
00126   }
00127   return nitem;
00128 }
00129 
00134 void SalomeApp_DataModelSync::deleteItemWithChildren( const suitPtr& p ) const
00135 {
00136   if( !p )
00137     return;
00138 
00139   DataObjectList ch;
00140   p->children( ch );
00141   DataObjectList::const_iterator anIt = ch.begin(), aLast = ch.end();
00142   for( ; anIt!=aLast; anIt++ )
00143     deleteItemWithChildren( *anIt );
00144   delete p;
00145 }
00146 
00152 bool SalomeApp_DataModelSync::isEqual( const kerPtr& p, const suitPtr& q ) const
00153 {
00154   LightApp_ModuleObject* lobj = dynamic_cast<LightApp_ModuleObject*>( q );
00155   SalomeApp_DataObject* sobj = dynamic_cast<SalomeApp_DataObject*>( q );
00156   _PTR( SComponent ) aComp( p );
00157   bool res = ( !p && !q ) ||
00158              ( lobj && !sobj && aComp ) ||
00159              ( sobj && isCorrect( p ) && p->GetID().c_str()==sobj->entry() );
00160   return res;
00161 }
00162 
00166 kerPtr SalomeApp_DataModelSync::nullSrc() const
00167 {
00168   return kerPtr();
00169 }
00170 
00174 suitPtr SalomeApp_DataModelSync::nullTrg() const
00175 {
00176   return 0;
00177 }
00178 
00184 QList<kerPtr> SalomeApp_DataModelSync::children( const kerPtr& obj ) const
00185 {
00186   QList<kerPtr> ch;
00187 
00188   _PTR( GenericAttribute ) anAttr;
00189   bool expandable = true;
00190   if ( obj && obj->FindAttribute( anAttr, "AttributeExpandable" ) ) {
00191     _PTR(AttributeExpandable) aAttrExp = anAttr;
00192     expandable = aAttrExp->IsExpandable();
00193   }
00194 
00195   if ( expandable ) {
00196     // tmp??
00197     _PTR(UseCaseBuilder) aUseCaseBuilder = myStudy->GetUseCaseBuilder();
00198     if (aUseCaseBuilder->HasChildren(obj)) {
00199       _PTR(UseCaseIterator) it ( aUseCaseBuilder->GetUseCaseIterator( obj ) );
00200       for ( ; it->More(); it->Next() )
00201         ch.append( it->Value() );
00202     }
00203     else {
00204       _PTR(ChildIterator) it ( myStudy->NewChildIterator( obj ) );
00205       for ( ; it->More(); it->Next() )
00206         ch.append( it->Value() );
00207     }
00208   }
00209 
00210   return ch;
00211 }
00212 
00218 QList<suitPtr> SalomeApp_DataModelSync::children( const suitPtr& p ) const
00219 {
00220   QList<suitPtr> ch;
00221   if ( p )
00222     ch = p->children();
00223   return ch;
00224 }
00225 
00230 suitPtr SalomeApp_DataModelSync::parent( const suitPtr& p ) const
00231 {
00232   return p ? p->parent(): 0;
00233 }
00234 
00239 void SalomeApp_DataModelSync::updateItem( const kerPtr& obj, const suitPtr& ) const
00240 {
00241 }
00242 
00246 void showTree( SUIT_DataObject* root )
00247 {
00248   qDebug( root ? "<tree>" : "<empty tree>" );
00249   if( !root )
00250     return;
00251 
00252   SUIT_DataObjectIterator it( root, SUIT_DataObjectIterator::DepthLeft );
00253   for( ; it.current(); ++it )
00254   {
00255     QString marg; marg.fill( ' ', 3*it.depth() );
00256     QString nnn = "%1 '%2'";
00257     qDebug( nnn.arg( marg ).arg( it.current()->name() ).toLatin1() );
00258   }
00259 }
00260 
00264 SalomeApp_DataModel::SalomeApp_DataModel( CAM_Module* theModule )
00265 : LightApp_DataModel( theModule )
00266 {
00267 }
00268 
00272 SalomeApp_DataModel::~SalomeApp_DataModel()
00273 {
00274 }
00275 
00279 bool SalomeApp_DataModel::open( const QString& name, CAM_Study* study, QStringList )
00280 {
00281   SalomeApp_Study* aDoc = dynamic_cast<SalomeApp_Study*>( study );
00282   if ( !aDoc )
00283     return false;
00284 
00285   QString anId = getRootEntry( aDoc );
00286   if ( anId.isEmpty() )
00287     return true; // Probably nothing to load
00288 
00289   _PTR(Study)      aStudy ( aDoc->studyDS() ); // shared_ptr cannot be used here
00290   _PTR(SComponent) aSComp ( aStudy->FindComponentID( std::string( anId.toLatin1() ) ) );
00291   if ( aSComp )
00292     updateTree( aSComp, aDoc );
00293 
00294   QStringList listOfFiles;
00295   LightApp_DataModel::open(name, study, listOfFiles);
00296   return true;
00297 }
00298 
00302 bool SalomeApp_DataModel::create( CAM_Study* theStudy )
00303 {
00304   update(NULL, (LightApp_Study*)theStudy);
00305   return true;
00306 }
00307 
00311 void SalomeApp_DataModel::update( LightApp_DataObject*, LightApp_Study* study )
00312 {
00313   SalomeApp_Study* aSStudy = dynamic_cast<SalomeApp_Study*>(study);
00314   LightApp_RootObject* studyRoot = 0;
00315   _PTR(SComponent) sobj;
00316   SalomeApp_DataObject* modelRoot = dynamic_cast<SalomeApp_DataObject*>( root() );
00317   if ( !modelRoot ){ // not yet connected to a study -> try using <study> argument
00318     if ( !aSStudy )
00319       aSStudy = dynamic_cast<SalomeApp_Study*>( getModule()->getApp()->activeStudy() );
00320     if ( aSStudy ){
00321       studyRoot = dynamic_cast<LightApp_RootObject*>( aSStudy->root() );
00322       QString anId = getRootEntry( aSStudy );
00323       if ( !anId.isEmpty() ){ // if nothing is published in the study for this module -> do nothing
00324         _PTR(Study) aStudy ( aSStudy->studyDS() );
00325         sobj = aStudy->FindComponentID( std::string( anId.toLatin1() ) );
00326       }
00327     }
00328   }
00329   else{
00330     studyRoot = dynamic_cast<LightApp_RootObject*>( modelRoot->root() );
00331     if ( studyRoot ) {
00332       aSStudy = dynamic_cast<SalomeApp_Study*>( studyRoot->study() ); // <study> value should not change here theoretically, but just to make sure
00333       if ( aSStudy ) {
00334         _PTR(Study) aStudy ( aSStudy->studyDS() );
00335         // modelRoot->object() cannot be reused here: it is about to be deleted by buildTree() soon
00336         sobj = aStudy->FindComponentID( std::string( modelRoot->entry().toLatin1() ) );
00337       }
00338     }
00339   }
00340   if ( sobj && aSStudy )
00341     updateTree( sobj, aSStudy );
00342 }
00343 
00347 SUIT_DataObject* SalomeApp_DataModel::synchronize( const _PTR( SComponent )& sobj, SalomeApp_Study* study )
00348 {
00349   if( !study || !study->root() || !sobj )
00350     return 0;
00351     
00352   DataObjectList ch; study->root()->children( ch );
00353   DataObjectList::const_iterator anIt = ch.begin(), aLast = ch.end();
00354   SUIT_DataObject* suitObj = 0;
00355   for( ; anIt!=aLast; anIt++ )
00356   {
00357     LightApp_DataObject* dobj = dynamic_cast<LightApp_DataObject*>( *anIt );
00358     if( dobj && dobj->name() == sobj->GetName().c_str() )
00359     {
00360       suitObj = dobj;
00361       break;
00362     }
00363   }
00364 
00365 #ifdef WITH_SALOMEDS_OBSERVER
00366   SalomeApp_RootObject* root=dynamic_cast<SalomeApp_RootObject*>(study->root());
00367   if(!(root->toSynchronize()))
00368     return suitObj;
00369 #endif
00370 
00371   SalomeApp_DataModelSync sync( study->studyDS(), study->root() );
00372 
00373   if( !suitObj || dynamic_cast<SalomeApp_DataObject*>( suitObj ) )
00374     suitObj= ::synchronize<kerPtr,suitPtr,SalomeApp_DataModelSync>( sobj, suitObj, sync );
00375   else
00376     suitObj= 0;
00377 
00378   return suitObj;
00379 }
00380 
00384 void SalomeApp_DataModel::updateTree( const _PTR( SComponent )& comp, SalomeApp_Study* study )
00385 {
00386   SalomeApp_ModuleObject* aNewRoot = dynamic_cast<SalomeApp_ModuleObject*>( synchronize( comp, study ) );
00387   if( aNewRoot )
00388   {
00389     aNewRoot->setDataModel( this );
00390     setRoot( aNewRoot );
00391   }
00392 }
00393 
00397 SalomeApp_Module* SalomeApp_DataModel::getModule() const
00398 {
00399   return dynamic_cast<SalomeApp_Module*>( module() );
00400 }
00401 
00405 SalomeApp_Study* SalomeApp_DataModel::getStudy() const
00406 {
00407   if(!root()) return 0;
00408   LightApp_RootObject* aRoot = dynamic_cast<LightApp_RootObject*>( root()->root() );
00409   if ( !aRoot )
00410     return 0;
00411   SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( aRoot->study() );
00412   if ( !aStudy )
00413     return 0;
00414   return aStudy;
00415 }
00416 
00420 QString SalomeApp_DataModel::getRootEntry( SalomeApp_Study* study ) const
00421 {
00422   QString anEntry;
00423   if ( root() && root()->root() ) { // data model already in a study
00424     SalomeApp_DataObject* anObj = dynamic_cast<SalomeApp_DataObject*>( root() );
00425     if ( anObj )
00426       anEntry = anObj->entry();
00427   }
00428   else if ( study && study->studyDS() ) { // this works even if <myRoot> is null
00429     _PTR(SComponent) aSComp( study->studyDS()->FindComponent( module()->name().toStdString() ) );
00430     if ( aSComp )
00431       anEntry = aSComp->GetID().c_str();
00432   }
00433   return anEntry;
00434 }