1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : SALOME_Notebook.cxx
23 // Author : Alexandre SOLOVYOV
27 #include <SALOME_Notebook.hxx>
28 #include <SALOME_Parameter.hxx>
29 #include <SALOME_EvalParser.hxx>
31 std::string arg( const std::string& theStr, const std::string& theArg1 )
33 std::string aRes = theStr;
36 int aPos = aRes.find( "%1" );
38 aRes.replace( aPos, 2, theArg1 );
45 std::string arg( const std::string& theStr, const std::string& theArg1, const std::string& theArg2 )
47 std::string aRes = theStr;
50 int aPos = aRes.find( "%1" );
52 aRes.replace( aPos, 2, theArg1 );
55 aPos = aRes.find( "%2" );
57 aRes.replace( aPos, 2, theArg2 );
65 std::vector<std::string> split( const std::string& theData, const std::string& theSeparator, bool theIsKeepEmpty )
67 std::vector<std::string> aParts;
68 int aPrev = 0, anInd = 0;
69 while( anInd<theData.length() )
71 anInd = theData.find( theSeparator, aPrev );
73 anInd = theData.length();
75 std::string aPart = theData.substr( aPrev, anInd - aPrev );
76 if( aPart.length() > 0 || theIsKeepEmpty )
77 aParts.push_back( aPart );
84 void save( FILE* theFile, const std::string& theData )
86 short len = theData.length();
87 fwrite( &len, 1, sizeof( short ), theFile );
88 fwrite( theData.c_str(), 1, len, theFile );
91 void save( FILE* theFile, int theData )
93 fwrite( &theData, 1, sizeof( int ), theFile );
96 bool load( FILE* theFile, std::string& theData )
99 int rlen = fread( &len, 1, sizeof( short ), theFile );
100 if( rlen < sizeof( short ) )
104 rlen = fread( buf, 1, len, theFile );
110 //printf( "load: %s\n", theData.c_str() );
114 bool load( FILE* theFile, int& theData )
116 int rlen = fread( &theData, 1, sizeof( int ), theFile );
117 if( rlen < sizeof( int ) )
120 //printf( "load: %i\n", theData );
131 SALOME_Notebook::KeyHelper::KeyHelper( const std::string& theKey, const SALOME_Notebook* theNotebook )
132 : myKey( theKey ), myNotebook( theNotebook )
136 std::string SALOME_Notebook::KeyHelper::key() const
141 bool SALOME_Notebook::KeyHelper::operator < ( const KeyHelper& theKH ) const
144 if( myNotebook->HasDependency( myKey, theKH.myKey ) )
146 else if( myNotebook->HasDependency( theKH.myKey, myKey ) )
150 SALOME::ParameterizedObject_var anObj1 = myNotebook->FindObject( myKey );
151 SALOME::ParameterizedObject_var anObj2 = myNotebook->FindObject( theKH.myKey );
152 SALOME::Parameter_var aParamV1 = SALOME::Parameter::_narrow( anObj1 );
153 SALOME::Parameter_var aParamV2 = SALOME::Parameter::_narrow( anObj2 );
154 if( CORBA::is_nil( aParamV1 ) )
155 if( CORBA::is_nil( aParamV2 ) )
156 ok = myKey < theKH.myKey;
160 if( CORBA::is_nil( aParamV2 ) )
164 SALOME_Parameter* aParam1 = myNotebook->GetParameterPtr( aParamV1->GetEntry() );
165 SALOME_Parameter* aParam2 = myNotebook->GetParameterPtr( aParamV2->GetEntry() );
166 ok = aParam1->GetId() < aParam2->GetId();
170 //printf( "%s < %s ? %i\n", myKey.c_str(), theKH.myKey.c_str(), ok );
174 bool SALOME_Notebook::KeyHelper::operator == ( const std::string& theKey ) const
176 return myKey == theKey;
184 SALOME_Notebook::SALOME_Notebook( PortableServer::POA_ptr thePOA, SALOMEDS::Study_ptr theStudy )
185 : SALOME::GenericObj_i( thePOA ), myUpdateOnlyParameters( false ), myMaxId( -1 )
187 myStudy = SALOMEDS::Study::_duplicate( theStudy );
190 void SALOME_Notebook::AddDependency( SALOME::ParameterizedObject_ptr theObj, SALOME::ParameterizedObject_ptr theRef )
192 AddDependency( GetKey( theObj ), GetKey( theRef ) );
195 void SALOME_Notebook::RemoveDependency( SALOME::ParameterizedObject_ptr theObj, SALOME::ParameterizedObject_ptr theRef )
197 //Utils_Locker lock( &myMutex );
199 std::string anObjKey = GetKey( theObj ), aRefKey = GetKey( theRef );
200 std::map< std::string, std::list<std::string> >::iterator it = myDependencies.find( anObjKey );
201 if( it == myDependencies.end() )
202 ThrowError( arg( "Dependency between '%1' and '%2' is not found", theObj->GetEntry(), theObj->GetEntry() ) );
204 it->second.remove( aRefKey );
207 void SALOME_Notebook::ClearDependencies( SALOME::ParameterizedObject_ptr theObj, SALOME::DependenciesType theType )
209 ClearDependencies( GetKey( theObj ), theType );
212 void SALOME_Notebook::SetToUpdate( SALOME::ParameterizedObject_ptr theObj )
214 //Utils_Locker lock( &myMutex );
216 //printf( "SetToUpdate: %s\n", GetKey( theObj ).c_str() );
218 SALOME::Parameter_var aParam = SALOME::Parameter::_narrow( theObj );
219 if( !CORBA::is_nil( aParam ) )
221 std::string anEntry = aParam->GetEntry();
222 std::map< std::string, SALOME_Parameter* >::const_iterator pit = myParameters.find( anEntry );
223 if( pit == myParameters.end() )
226 SALOME_Parameter* aParamPtr = pit->second;
227 std::string aKey = GetKey( anEntry );
228 ClearDependencies( aKey, SALOME::All );
229 AddDependencies( aParamPtr );
233 printf( "Dependencies:\n" );
234 std::map< std::string, std::list<std::string> >::const_iterator mit = myDependencies.begin(), mlast = myDependencies.end();
235 for( ; mit!=mlast; mit++ )
237 printf( "%s -> [ ", mit->first.c_str() );
238 std::list<std::string>::const_iterator lit = mit->second.begin(), llast = mit->second.end();
239 for( ; lit!=llast; lit++ )
240 printf( "%s ", (*lit).c_str() );
245 std::string anObjKey = GetKey( theObj );
246 std::list<std::string> aDeps = GetAllDependingOn( anObjKey );
247 std::list<std::string>::const_iterator it = aDeps.begin(), last = aDeps.end();
248 for( ; it!=last; it++ )
249 if( find( myToUpdate.begin(), myToUpdate.end(), *it ) == myToUpdate.end() )
250 myToUpdate.push_back( KeyHelper( *it, this ) );
255 uit = myToUpdate.begin(); ulast = myToUpdate.end();
256 for( ; uit!=ulast; uit++ )
257 printf( "To update: %s\n", (*uit).key().c_str() );
260 //printf( "Dump after SetToUpdate:\n" );
264 bool SALOME_Notebook::CanUpdate( SALOME::ParameterizedObject_ptr theObj ) const
266 if( CORBA::is_nil( theObj ) )
269 SALOME::Parameter_var aParam = SALOME::Parameter::_narrow( theObj );
270 return !myUpdateOnlyParameters || !CORBA::is_nil( aParam );
273 void SALOME_Notebook::Update()
278 void SALOME_Notebook::Update( bool theOnlyParameters )
280 myUpdateOnlyParameters = theOnlyParameters;
281 //Utils_Locker lock( &myMutex );
283 //1. Simple recompute
284 std::list< KeyHelper > aPostponedUpdate;
285 std::list<KeyHelper>::const_iterator it = myToUpdate.begin(), last = myToUpdate.end();
286 for( ; it!=last; it++ )
288 std::string aKey = (*it).key();
289 //printf( "key = %s\n", aKey.c_str() );
290 SALOME::ParameterizedObject_var anObj = FindObject( aKey );
291 if( CanUpdate( anObj ) )
292 anObj->Update( _this() );
294 aPostponedUpdate.push_back( *it );
296 myToUpdate = aPostponedUpdate;
299 std::list<SubstitutionInfo>::iterator sit = mySubstitutions.begin(), slast = mySubstitutions.end(), sremove;
302 if( Substitute( *sit ) )
306 mySubstitutions.erase( sremove );
313 bool SALOME_Notebook::Substitute( SubstitutionInfo& theSubstitution )
315 std::list< KeyHelper > aPostponedUpdate;
317 anOldName = theSubstitution.myName,
318 aNewName = theSubstitution.myExpr;
319 bool isRename = theSubstitution.myIsRename;
320 SALOME_EvalExpr anExpr;
321 anExpr.setExpression( theSubstitution.myExpr );
323 std::list<KeyHelper>::const_iterator it = theSubstitution.myObjects.begin(), last = theSubstitution.myObjects.end();
324 for( ; it!=last; it++ )
326 SALOME::ParameterizedObject_var anObj = FindObject( it->key() );
327 if( !CanUpdate( anObj ) )
329 aPostponedUpdate.push_back( *it );
333 SALOME::Parameter_var aParam = SALOME::Parameter::_narrow( anObj );
334 if( CORBA::is_nil( aParam ) )
337 SALOME::StringArray_var aParams = anObj->GetParameters();
338 int n = aParams->length();
339 //printf( "get params: %i\n", n );
340 for( int i=0; i<n; i++ )
342 //printf( "\t%s\n", aParams[i].in() );
343 if( anOldName == aParams[i].in() )
346 AddExpression( aNewName.c_str() );
347 aParams[i] = CORBA::string_dup( aNewName.c_str() );
350 anObj->SetParameters( _this(), aParams );
355 aName = aParam->GetEntry(),
356 anOldKey = GetKey( aName ),
357 aNewKey = GetKey( aNewName );
358 SALOME_Parameter* aParamPtr = myParameters[aName];
360 aParamPtr->Substitute( anOldName, aNewName );
361 if( aName == anOldName )
363 //it is renamed parameter
365 //1. update parameters map
368 std::list<std::string> aDeps = myDependencies[anOldKey];
369 myDependencies.erase( anOldKey );
370 if( aDeps.size() > 0 )
371 myDependencies[aNewKey] = aDeps;
373 myParameters.erase( anOldName );
374 myParameters[aNewName] = aParamPtr;
378 ClearDependencies( anOldKey, SALOME::All );
379 myParameters.erase( aName );
382 //2. update dependencies map
383 std::map< std::string, std::list<std::string> >::iterator it = myDependencies.begin(), last = myDependencies.end();
384 for( ; it!=last; it++ )
386 std::list<std::string>::iterator dit = it->second.begin(), dlast = it->second.end(), dremove;
388 if( *dit == anOldKey )
399 it->second.erase( dremove );
408 theSubstitution.myObjects = aPostponedUpdate;
409 return theSubstitution.myObjects.size() == 0;
412 void SALOME_Notebook::AddExpression( const char* theExpr )
414 AddParameter( new SALOME_Parameter( this, theExpr ) );
417 void SALOME_Notebook::AddNamedExpression( const char* theName, const char* theExpr )
419 AddParameter( new SALOME_Parameter( this, theName, theExpr, true ) );
422 void SALOME_Notebook::AddBoolean( const char* theName, CORBA::Boolean theValue )
424 AddParameter( new SALOME_Parameter( this, theName, theValue ) );
427 void SALOME_Notebook::AddInteger( const char* theName, CORBA::Long theValue )
429 AddParameter( new SALOME_Parameter( this, theName, (int)theValue ) );
432 void SALOME_Notebook::AddReal( const char* theName, CORBA::Double theValue )
434 AddParameter( new SALOME_Parameter( this, theName, theValue ) );
437 void SALOME_Notebook::AddString( const char* theName, const char* theValue )
439 AddParameter( new SALOME_Parameter( this, theName, theValue, false ) );
442 SALOME_Notebook::SubstitutionInfo SALOME_Notebook::CreateSubstitution( const std::string& theName, const std::string& theExpr, bool theIsRename ) const
444 SubstitutionInfo anInfo;
445 anInfo.myName = theName;
446 anInfo.myExpr = theExpr;
447 anInfo.myIsRename = theIsRename;
448 std::list<std::string> aDeps = GetAllDependingOn( GetKey( theName ) );
449 anInfo.myObjects.clear();
450 std::list<std::string>::const_iterator dit = aDeps.begin(), dlast = aDeps.end();
451 for( ; dit!=dlast; dit++ )
452 anInfo.myObjects.push_back( KeyHelper( *dit, this ) );
453 Sort( anInfo.myObjects );
457 void SALOME_Notebook::AddSubstitution( const std::string& theName, const std::string& theExpr, bool theIsRename )
459 mySubstitutions.push_back( CreateSubstitution( theName, theExpr, theIsRename ) );
462 void SALOME_Notebook::Rename( const char* theOldName, const char* theNewName )
464 SALOME_Parameter* aParam = GetParameterPtr( theOldName );
467 aMsg = arg( "Name '%1' does not exist", theOldName );
468 else if( aParam->IsAnonymous() )
469 aMsg = arg( "Parameter '%1' is anonymous", theOldName );
470 else if( GetParameterPtr( theNewName ) )
471 aMsg = arg( "New name '%1' is already used", theNewName );
473 CheckParamName( theNewName, aMsg );
475 if( aMsg.length() == 0 )
477 AddSubstitution( theOldName, theNewName, true );
484 void SALOME_Notebook::Remove( const char* theParamName )
486 SALOME_Parameter* aParam = GetParameterPtr( theParamName );
490 if( aParam->IsCalculable() )
491 anExpr = aParam->GetExpression( false );
493 anExpr = aParam->AsString();
494 AddSubstitution( theParamName, anExpr, false );
498 ThrowError( arg( "The parameter '%1' is not found", theParamName ) );
501 void SALOME_Notebook::UpdateAnonymous( const std::string& theOldName, const std::string& theNewName )
503 SubstitutionInfo anInfo = CreateSubstitution( theOldName, theNewName, true );
504 Substitute( anInfo );
507 SALOME::StringArray* SALOME_Notebook::GenerateList( const std::list<std::string>& theList ) const
509 SALOME::StringArray_var aRes = new SALOME::StringArray();
510 aRes->length( theList.size() );
511 std::list<std::string>::const_iterator nit = theList.begin(), nlast = theList.end();
512 for( int i=0; nit!=nlast; nit++, i++ )
513 aRes[i] = CORBA::string_dup( nit->c_str() );
521 ParameterRank( SALOME_Parameter* theParam )
523 myName = theParam->GetEntry();
524 myId = theParam->GetId();
527 bool operator < ( const ParameterRank& theRank )
529 return myId < theRank.myId;
532 bool operator == ( const ParameterRank& theRank )
534 return myId == theRank.myId && myName == theRank.myName;
537 std::string name() const
547 std::list<std::string> SALOME_Notebook::Parameters( bool theWithAnonymous ) const
549 std::list<ParameterRank> aParams;
550 std::map< std::string, SALOME_Parameter* >::const_iterator it = myParameters.begin(), last = myParameters.end();
551 for( ; it!=last; it++ )
553 ParameterRank aRank( it->second );
554 if( ( theWithAnonymous || !it->second->IsAnonymous() ) &&
555 find( aParams.begin(), aParams.end(), aRank ) == aParams.end() )
556 aParams.push_back( aRank );
560 std::list<std::string> aNames;
561 std::list<ParameterRank>::const_iterator pit = aParams.begin(), plast = aParams.end();
562 for( ; pit!=plast; pit++ )
563 aNames.push_back( pit->name() );
568 SALOME::StringArray* SALOME_Notebook::Parameters()
570 //Utils_Locker lock( &myMutex );
572 return GenerateList( Parameters( false ) );
575 SALOME::StringArray* SALOME_Notebook::AbsentParameters( const char* theExpr )
577 //Utils_Locker lock( &myMutex );
579 std::list<std::string> anAbsents;
581 SALOME_EvalExpr anExpr( theExpr );
582 if( anExpr.parser()->error() == EvalExpr_OK )
584 std::list<std::string> aParams = anExpr.parser()->parameters();
585 std::list<std::string>::const_iterator it = aParams.begin(), last = aParams.end();
586 for( ; it!=last; it++ )
587 if( !GetParameterPtr( it->c_str() ) &&
588 find( anAbsents.begin(), anAbsents.end(), *it ) == anAbsents.end() )
589 anAbsents.push_back( *it );
593 return GenerateList( anAbsents );
596 SALOME::Parameter_ptr SALOME_Notebook::GetParameter( const char* theParamName )
598 //printf( "Param, name = %s\n", theParamName );
599 SALOME_Parameter* aParam = GetParameterPtr( theParamName );
600 //printf( "Result = %i\n", (int)aParam );
601 SALOME::Parameter_var aRes;
603 aRes = aParam->_this();
607 SALOME_Parameter* SALOME_Notebook::GetParameterPtr( const char* theParamName ) const
609 //Utils_Locker lock( const_cast<Utils_Mutex*>( &myMutex ) );
611 std::map< std::string, SALOME_Parameter* >::const_iterator it = myParameters.find( theParamName );
612 return it==myParameters.end() ? 0 : it->second;
615 void SALOME_Notebook::AddParameter( SALOME_Parameter* theParam, bool theAddDependencies )
617 //Utils_Locker lock( &myMutex );
619 std::string anEntry = theParam->GetEntry(), aMsg;
620 if( !theParam->IsAnonymous() && !CheckParamName( anEntry, aMsg ) )
623 //printf( "Add param: %s\n", anEntry.c_str() );
625 std::map< std::string, SALOME_Parameter* >::const_iterator it = myParameters.find( anEntry );
626 bool exists = it!=myParameters.end();
628 ThrowError( arg( "The parameter '%1' already exists", anEntry ) );
632 myParameters[anEntry] = theParam;
633 if( theAddDependencies && !exists )
634 AddDependencies( theParam );
636 catch( const SALOME::NotebookError& ex )
638 Remove( anEntry.c_str() );
643 void SALOME_Notebook::AddDependencies( SALOME_Parameter* theParam )
645 //Utils_Locker lock( &myMutex );
647 //printf( "Dependencies search\n" );
648 std::string anEntry = theParam->GetEntry();
649 std::string aParamKey = GetKey( anEntry );
650 SALOME_StringList aDeps = theParam->Dependencies();
651 SALOME_StringList::const_iterator dit = aDeps.begin(), dlast = aDeps.end();
652 for( ; dit!=dlast; dit++ )
654 std::string aKey = GetKey( *dit );
655 AddDependency( aParamKey, aKey );
656 //printf( "add dep to %s, res = %i\n", aKey.c_str(), ok );
660 void SALOME_Notebook::AddDependency( const std::string& theObjKey, const std::string& theRefKey )
662 //Utils_Locker lock( &myMutex );
663 std::string anObjName, aRefName;
664 GetComponent( theObjKey, anObjName );
665 GetComponent( theRefKey, aRefName );
667 std::list<std::string> aDeps = GetAllDependingOn( theObjKey );
668 if( find( aDeps.begin(), aDeps.end(), theRefKey ) != aDeps.end () )
669 ThrowError( arg( "Dependency %1 -> %2 creates a cyclic dependency", anObjName, aRefName ) );
670 //after creation a cyclic dependency could appear
672 std::list<std::string>& aList = myDependencies[theObjKey];
673 bool ok = find( aList.begin(), aList.end(), theRefKey ) == aList.end();
675 aList.push_back( theRefKey );
677 // ThrowError( arg( "Dependency %1 -> %2 is already created", anObjName, aRefName ) );
680 void SALOME_Notebook::ClearDependencies( const std::string& theObjKey, SALOME::DependenciesType theType )
682 //Utils_Locker lock( &myMutex );
684 //printf( "Clear dependencies: %s\n", theObjKey.c_str() );
686 std::map< std::string, std::list<std::string> >::iterator it = myDependencies.find( theObjKey );
687 if( it == myDependencies.end() )
690 std::list<std::string> aNewDeps;
691 if( theType != SALOME::All )
693 std::list<std::string>::const_iterator dit = it->second.begin(), dlast = it->second.end();
694 for( ; dit!=dlast; dit++ )
696 SALOME::ParameterizedObject_var anObj = FindObject( *dit );
697 SALOME::Parameter_var aParam = SALOME::Parameter::_narrow( anObj );
698 if( ( !CORBA::is_nil( aParam ) && theType == SALOME::Objects ) || theType == SALOME::Parameters )
699 aNewDeps.push_back( *dit );
703 if( aNewDeps.size() == 0 )
704 myDependencies.erase( theObjKey );
706 it->second = aNewDeps;
709 std::string SALOME_Notebook::GetKey( SALOME::ParameterizedObject_ptr theObj ) const
711 return GetKey( theObj->GetComponent(), theObj->GetEntry() );
714 std::string SALOME_Notebook::GetKey( const std::string& theComponent, const std::string& theEntry ) const
716 return arg( "%1#%2", theComponent, theEntry );
719 std::string SALOME_Notebook::GetKey( const std::string& theParamName ) const
721 return GetKey( PARAM_COMPONENT, theParamName );
724 std::list<std::string> SALOME_Notebook::GetAllDependingOn( const std::string& theKey ) const
726 //Utils_Locker lock( &myMutex );
728 std::list<std::string> aDeps, aCurrents, aNewCurrents;
729 aCurrents.push_back( theKey );
730 aDeps.push_back( theKey );
731 while( aCurrents.size() > 0 )
733 aNewCurrents.clear();
734 std::list<std::string>::const_iterator cit = aCurrents.begin(), clast = aCurrents.end();
735 for( ; cit!=clast; cit++ )
737 //printf( "Check of %s:\n", (*cit).c_str() );
738 std::map< std::string, std::list<std::string> >::const_iterator dit = myDependencies.begin(), dlast = myDependencies.end();
739 for( ; dit!=dlast; dit++ )
741 std::string k = dit->first;
742 //printf( "\t%s\n", k.c_str() );
743 if( find( dit->second.begin(), dit->second.end(), *cit ) != dit->second.end() &&
744 find( aDeps.begin(), aDeps.end(), k ) == aDeps.end() )
746 //printf( "\t\tadd\n" );
747 aNewCurrents.push_back( k );
748 aDeps.push_back( k );
753 aCurrents = aNewCurrents;
758 std::string SALOME_Notebook::GetComponent( const std::string& theKey, std::string& theEntry ) const
760 int aPos = theKey.find( "#" );
761 theEntry = theKey.substr( aPos+1, theKey.length()-aPos-1 );
762 return theKey.substr( 0, aPos );
765 SALOME::ParameterizedObject_ptr SALOME_Notebook::FindObject( const std::string& theKey ) const
767 SALOME::ParameterizedObject_var aPObj;
768 std::string anEntry, aComponent = GetComponent( theKey, anEntry );
769 if( aComponent == PARAM_COMPONENT ) {
770 SALOME_Notebook* that = const_cast<SALOME_Notebook*>( this );
771 aPObj = that->GetParameter( anEntry.c_str() );
774 SALOME::GenericObj_var anObject = myStudy->FindObjectByInternalEntry( aComponent.c_str(), anEntry.c_str() );
775 aPObj = SALOME::ParameterizedObject::_narrow( anObject );
777 return aPObj._retn();
780 CORBA::Boolean SALOME_Notebook::Save( const char* theFileName )
782 //printf( "SALOME_Notebook::Save into %s\n", theFileName );
784 FILE* aFile = fopen( theFileName, "w" );
788 save( aFile, "notebook" );
790 //1. Save dependencies
791 save( aFile, "dependencies" );
792 std::map< std::string, std::list<std::string> >::const_iterator dit = myDependencies.begin(), dlast = myDependencies.end();
793 for( ; dit!=dlast; dit++ )
795 save( aFile, dit->first );
796 std::list<std::string>::const_iterator it = dit->second.begin(), last = dit->second.end();
797 for( ; it!=last; it++ )
799 save( aFile, "end" );
803 save( aFile, "parameters" );
804 std::list<std::string> aNames = Parameters( true );
805 std::list<std::string>::const_iterator pit = aNames.begin(), plast = aNames.end();
806 for( ; pit!=plast; pit++ )
807 myParameters[*pit]->Save( aFile );
809 //3. Save update list
810 save( aFile, "recompute list" );
811 std::list< KeyHelper >::const_iterator uit = myToUpdate.begin(), ulast = myToUpdate.end();
812 for( ; uit!=ulast; uit++ )
813 save( aFile, uit->key() );
815 //4. Save substitutions list
816 save( aFile, "substitutions" );
817 std::list<SubstitutionInfo>::const_iterator sit = mySubstitutions.begin(), slast = mySubstitutions.end();
818 for( ; sit!=slast; sit++ )
825 bool SALOME_Notebook::Save( FILE* theFile, const SubstitutionInfo& theSubstitution ) const
827 save( theFile, theSubstitution.myName );
828 save( theFile, theSubstitution.myExpr );
829 save( theFile, theSubstitution.myIsRename );
830 std::list< KeyHelper >::const_iterator it = theSubstitution.myObjects.begin(), last = theSubstitution.myObjects.end();
831 for( ; it!=last; it++ )
832 save( theFile, it->key() );
833 save( theFile, "end" );
837 SALOME_Notebook::SubstitutionInfo SALOME_Notebook::Load( FILE* theFile, const std::string& theFirstLine ) const
839 SubstitutionInfo aSubstitution;
840 aSubstitution.myName = theFirstLine;
841 load( theFile, aSubstitution.myExpr );
842 int isRename; load( theFile, isRename );
843 aSubstitution.myIsRename = isRename;
848 load( theFile, aLine );
851 aSubstitution.myObjects.push_back( KeyHelper( aLine, this ) );
853 return aSubstitution;
858 typedef enum { Start, Title, Dependencies, Parameters, Recompute, Substitute } LoadState;
861 CORBA::Boolean SALOME_Notebook::Load( const char* theFileName )
863 State::LoadState aState = State::Start;
864 FILE* aFile = fopen( theFileName, "r" );
874 if( !load( aFile, aLine ) )
877 if( aState == State::Start && aLine == "notebook" )
878 aState = State::Title;
879 else if( aLine == "dependencies" )
880 aState = State::Dependencies;
881 else if( aLine == "parameters" )
882 aState = State::Parameters;
883 else if( aLine == "recompute list" )
884 aState = State::Recompute;
885 else if( aLine == "substitutions" )
886 aState = State::Substitute;
888 else switch( aState )
895 case State::Dependencies:
896 ParseDependencies( aFile, aLine );
899 case State::Parameters:
901 SALOME_Parameter* aParam = SALOME_Parameter::Load( this, aFile, aLine );
903 AddParameter( aParam, false );
909 case State::Recompute:
910 myToUpdate.push_back( KeyHelper( aLine, this ) );
913 case State::Substitute:
914 mySubstitutions.push_back( Load( aFile, aLine ) );
919 catch( const SALOME::NotebookError& ex )
921 printf( "Exception: %s\n", ex.Reason.in() );
929 void SALOME_Notebook::ParseDependencies( FILE* theFile, const std::string& theFirstLine )
931 std::string aKey = theFirstLine, aLine;
934 load( theFile, aLine );
937 AddDependency( aKey, aLine );
941 char* SALOME_Notebook::DumpPython()
945 aRes = "from salome_notebook import *\n\n";
946 std::list< KeyHelper > aParams;
947 //printf( "%i\n", myParameters.size() );
948 std::map< std::string, SALOME_Parameter* >::const_iterator it = myParameters.begin(), last = myParameters.end();
949 for( ; it!=last; it++ )
950 aParams.push_back( KeyHelper( it->first, this ) );
952 printf( "%i\n", aParams.size() );
954 printf( "%i\n", aParams.size() );
955 std::list< KeyHelper >::const_iterator pit = aParams.begin(), plast = aParams.end();
957 for( ; pit!=plast; pit++ )
959 GetComponent( pit->key(), anEntry );
961 SALOME_Parameter* aParam = GetParameterPtr( anEntry.c_str() );
962 if( !aParam || aParam->IsAnonymous() )
965 aRes += "notebook.set( ";
969 if( aParam->IsCalculable() )
972 aRes += aParam->GetExpression( false );
976 aRes += aParam->AsString();
981 return CORBA::string_dup( aRes.c_str() );
984 bool SALOME_Notebook::CheckParamName( const std::string& theParamName, std::string& theMsg ) const
986 int len = theParamName.length();
989 theMsg = "The name should not be empty";
993 if( isdigit( theParamName[0] ) )
995 theMsg = "The name should not start by a digit";
999 for( int i=0, n=theParamName.length(); i<n; i++ )
1000 if( isspace( theParamName[i] ) )
1002 theMsg = "The name should not contain white symbols";
1006 SALOME_EvalExpr anExpr( theParamName );
1007 bool ok = anExpr.parser()->isMonoParam();
1009 theMsg = "The name should not be expression";
1013 void SALOME_Notebook::Sort( std::list< KeyHelper >& theList ) const
1015 std::list<KeyHelper>::iterator uit = theList.begin(), uit1, ulast = theList.end();
1016 for( ; uit!=ulast; uit++ )
1017 for( uit1=uit, uit1++; uit1!=ulast; uit1++ )
1020 KeyHelper tmp = *uit1;
1026 char* SALOME_Notebook::Dump()
1031 aStr += "==========================\n";
1032 aStr += "=== NOTEBOOK Dump: ===\n";
1033 aStr += "==========================\n\n";
1034 aStr += "Dependencies:\n";
1035 std::map< std::string, std::list<std::string> >::const_iterator dit = myDependencies.begin(), dlast = myDependencies.end();
1036 for( ; dit!=dlast; dit++ )
1040 std::list<std::string>::const_iterator it = dit->second.begin(), last = dit->second.end();
1041 for( ; it!=last; it++ )
1048 aStr += "Parameters:\n";
1049 std::list<std::string> aNames = Parameters( true );
1050 std::list<std::string>::const_iterator pit = aNames.begin(), plast = aNames.end();
1051 for( ; pit!=plast; pit++ )
1053 SALOME_Parameter* p = myParameters[*pit];
1054 aStr += *pit + " (" + p->GetEntry() + "): ";
1056 char buf[16]; sprintf( buf, "%i", p->GetId() );
1057 aStr += arg( "[%1] ", buf );
1059 if( p->IsAnonymous() )
1061 if( p->IsCalculable() )
1062 aStr += std::string( p->GetExpression( false ) ) + " (val=" + p->AsString() + ")";
1064 aStr += p->AsString();
1070 aStr += "Update lists:\n";
1071 aStr += "\tSimple recompute:\n";
1072 std::list< KeyHelper >::const_iterator uit = myToUpdate.begin(), ulast = myToUpdate.end();
1073 for( ; uit!=ulast; uit++ )
1074 aStr += "\t" + uit->key() + "\n";
1076 aStr += "\tSubstitutions:\n";
1077 std::list<SubstitutionInfo>::const_iterator sit = mySubstitutions.begin(), slast = mySubstitutions.end();
1078 for( ; sit!=slast; sit++ )
1080 aStr += "\t" + sit->myName;
1081 aStr += " -> " + sit->myExpr + ": ";
1082 std::list< KeyHelper >::const_iterator oit = sit->myObjects.begin(), olast = sit->myObjects.end();
1083 for( ; oit!=olast; oit++ )
1084 aStr += oit->key() + " ";
1088 return CORBA::string_dup( aStr.c_str() );
1091 void SALOME_Notebook::ThrowError( const std::string& theErrorMsg ) const
1093 SALOME::NotebookError anError;
1094 anError.Reason = CORBA::string_dup( theErrorMsg.c_str() );
1098 SALOME::StringArray* SALOME_Notebook::GetObjectParameters( const char* theComponent, const char* theEntry )
1100 std::list<std::string> aDeps;
1101 std::string aKey = GetKey( theComponent, theEntry ), aComponent, aName;
1102 std::map< std::string, std::list<std::string> >::const_iterator it = myDependencies.find( aKey );
1103 if( it!=myDependencies.end() )
1105 std::list<std::string>::const_iterator dit = it->second.begin(), dlast = it->second.end();
1106 for( ; dit!=dlast; dit++ )
1108 aComponent = GetComponent( *dit, aName );
1109 if( aComponent==PARAM_COMPONENT )
1110 aDeps.push_back( aName );
1114 return GenerateList( aDeps );
1117 SALOME::StringArray* SALOME_Notebook::GetParameters( const char* theParamName )
1119 return GetObjectParameters( PARAM_COMPONENT.c_str(), theParamName );
1122 int SALOME_Notebook::GetNewId()
1127 bool SALOME_Notebook::HasDependency( const std::string& theObjKey, const std::string& theRefKey ) const
1129 std::map< std::string, std::list<std::string> >::const_iterator it = myDependencies.find( theObjKey );
1130 return it==myDependencies.end() ? false : find( it->second.begin(), it->second.end(), theRefKey ) != it->second.end();
1133 SALOME::Parameter_ptr SALOME_Notebook::Calculate( const char* theExpr )
1135 if( CORBA::is_nil( myTmpParam ) )
1137 SALOME_Parameter* aParam = new SALOME_Parameter( this, "__tmp__", 0.0 );
1138 myTmpParam = aParam->_this();
1141 myTmpParam->SetExpression( theExpr );
1142 myTmpParam->Update( _this() );
1143 return myTmpParam.in();
1146 void SALOME_Notebook::ParseOldStyleParam( const std::string& theName, const std::string& theType, const std::string& theValue )
1149 if( sscanf( theType.c_str(), "%i", &aType ) != 1 )
1157 if( sscanf( theValue.c_str(), "%lf", &aValue ) != 1 )
1160 AddReal( theName.c_str(), aValue );
1166 if( sscanf( theValue.c_str(), "%i", &aValue ) != 1 )
1169 AddInteger( theName.c_str(), aValue );
1175 if( sscanf( theValue.c_str(), "%i", &aValue ) != 1 )
1178 AddBoolean( theName.c_str(), aValue );
1183 std::string aValue = theValue;
1184 for( int i = 0, n = aValue.length(); i < n; i++ )
1185 if( aValue[i]=='"' )
1188 AddNamedExpression( theName.c_str(), aValue.c_str() );
1194 void SALOME_Notebook::ParseOldStyleObject( const std::string& theComponent, const std::string& theEntry, const std::string& theData )
1196 //printf( "ParseOldStyleObject: %s\n", theData.c_str() );
1197 std::string anObjKey = GetKey( theComponent, theEntry );
1198 std::vector<std::string> aParts = split( theData, "|", false ), anItems;
1199 for( int i=0, n=aParts.size(); i<n; i++ )
1201 //printf( "part: %s\n", aParts[i].c_str() );
1202 anItems = split( aParts[i], ":", false );
1203 //printf( "size = %i\n", anItems.size() );
1204 for( int j=0, m=anItems.size(); j<m; j++ )
1206 std::string aRefKey = GetKey( anItems[j] );
1207 //printf( "key = %s\n", aRefKey.c_str() );
1208 if( !HasDependency( anObjKey, aRefKey ) )
1209 AddDependency( anObjKey, aRefKey );
1212 myEntriesToRebuild.push_back( theEntry );
1215 void SALOME_Notebook::RebuildLinks()
1217 printf( "Rebuild links\n" );
1219 SALOMEDS::StudyBuilder_var aBuilder = myStudy->NewBuilder();
1220 std::list<std::string> aNewEntriesToRebuild;
1221 std::list<std::string>::const_iterator it = myEntriesToRebuild.begin(), last = myEntriesToRebuild.end();
1222 for( ; it!=last; it++ )
1224 std::string aGlobalEntry = *it;
1225 SALOMEDS::SObject_var anObj = myStudy->FindObjectID( aGlobalEntry.c_str() );
1226 if( !CORBA::is_nil( anObj ) )
1228 SALOMEDS::GenericAttribute_var anAttr;
1229 if( aBuilder->FindAttribute( anObj._retn(), anAttr, "AttributeIOR" ) )
1231 /*SALOMEDS::AttributeIOR_var anIOR = SALOMEDS::AttributeIOR::_narrow( anAttr );
1232 CORBA::Object_var aRealObj = _orb->string_to_object( anIOR.Value() );
1233 SALOME::ParameterizedObject_var aParamObj = SALOME::ParameterizedObject::_narrow( aRealObj );
1234 if( !CORBA::is_nil( aParamObj ) )
1237 anOldKey = GetKey( aParamObj->GetComponent(), aGlobalEntry ),
1238 aKey = GetKey( aParamObj );
1239 std::map< std::string, std::list<std::string> >::iterator it = myDependencies.find( anOldKey );
1240 if( it!=myDependencies.end() )
1242 std::list<std::string> aValue = it->second;
1243 myDependencies.remove( anOldKey );
1244 myDependencies.insert( aKey, aValue );
1250 aNewEntriesToRebuild.push_back( aGlobalEntry );
1253 myEntriesToRebuild = aNewEntriesToRebuild;