Salome HOME
Join modifications from branch OCC_development_for_3_2_0a2
[modules/gui.git] / src / SalomeApp / SalomeApp_Study.cxx
1 // Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
2 // 
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.
7 // 
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.
12 //
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
16 //
17 // See http://www.salome-platform.org/
18 //
19 #include "SalomeApp_Study.h"
20
21 #include "SalomeApp_Module.h"
22 #include "SalomeApp_DataModel.h"
23 #include "SalomeApp_DataObject.h"
24 #include "SalomeApp_Application.h"
25 #include "SalomeApp_Engine_i.hxx"
26 #include "SalomeApp_VisualState.h"
27
28 #include "LightApp_RootObject.h"
29
30 #include <OB_Browser.h>
31
32 #include <SUIT_ResourceMgr.h>
33
34 #include <qptrlist.h>
35 #include <qapplication.h>
36 #include <qdict.h>
37
38 #include "utilities.h"
39 #include <iostream.h>
40 #include <string>
41 #include <vector>
42
43 #include <SUIT_Session.h>
44
45 #include "SALOMEDS_Tool.hxx"
46
47 #include "SALOMEDS_IParameters.hxx"
48
49 #include <SALOMEconfig.h>
50 #include CORBA_SERVER_HEADER(SALOME_Exception)
51
52 using namespace std;
53
54 /*!
55   Constructor.
56 */
57 SalomeApp_Study::SalomeApp_Study( SUIT_Application* app )
58 : LightApp_Study( app )
59 {
60 }  
61
62 /*!
63   Destructor.
64 */
65 SalomeApp_Study::~SalomeApp_Study()
66 {
67 }
68
69 /*!
70   Gets study id.
71 */
72 int SalomeApp_Study::id() const
73 {
74   int id = -1;
75   if ( myStudyDS )
76     id = studyDS()->StudyId();
77   return id;
78 }
79
80 /*!
81   Gets studyDS pointer.
82 */
83 _PTR(Study) SalomeApp_Study::studyDS() const
84 {
85   return myStudyDS;
86 }
87
88 /*!
89   Create document.
90 */
91 void SalomeApp_Study::createDocument()
92 {
93   MESSAGE( "openDocument" );
94
95   // initialize myStudyDS, read HDF file
96   QString aName = newStudyName();
97   _PTR(Study) study ( SalomeApp_Application::studyMgr()->NewStudy( aName.latin1() ) );
98   if ( !study )
99     return;
100
101   setStudyDS( study );
102   setStudyName( aName );
103
104   // create myRoot
105   setRoot( new LightApp_RootObject( this ) );
106
107   CAM_Study::createDocument();
108   emit created( this );
109 }
110
111 //=======================================================================
112 // name    : openDocument
113 /*! Purpose : Open document*/
114 //=======================================================================
115 bool SalomeApp_Study::openDocument( const QString& theFileName )
116 {
117   MESSAGE( "openDocument" );
118
119   // initialize myStudyDS, read HDF file
120   _PTR(Study) study ( SalomeApp_Application::studyMgr()->Open( (char*) theFileName.latin1() ) );
121   if ( !study )
122     return false;
123
124   setStudyDS( study );
125
126   setRoot( new LightApp_RootObject( this ) ); // create myRoot
127
128   // update loaded data models: call open() and update() on them.
129   ModelList dm_s;
130   dataModels( dm_s );
131   for ( ModelListIterator it( dm_s ); it.current(); ++it )
132     openDataModel( studyName(), it.current() );
133
134   // this will build a SUIT_DataObject-s tree under myRoot member field
135   // passing "false" in order NOT to rebuild existing data models' trees - it was done in previous step
136   // but tree that corresponds to not-loaded data models will be updated any way. 
137   ((SalomeApp_Application*)application())->updateObjectBrowser( false ); 
138
139   bool res = CAM_Study::openDocument( theFileName );
140   
141   emit opened( this );
142   study->IsSaved(true);
143
144   bool restore = application()->resourceMgr()->booleanValue( "Study", "store_visual_state", true );
145   if ( restore ) {
146     std::vector<int> savePoints = getSavePoints();
147     if ( savePoints.size() > 0 )
148       SalomeApp_VisualState( (SalomeApp_Application*)application() ).restoreState( savePoints[savePoints.size()-1] );
149   }
150
151   return res;
152 }
153
154 //=======================================================================
155 // name    : loadDocument
156 /*! Purpose : Connects GUI study to SALOMEDS one already loaded into StudyManager*/
157 //=======================================================================
158 bool SalomeApp_Study::loadDocument( const QString& theStudyName )
159 {
160   MESSAGE( "loadDocument" );
161
162   // obtain myStudyDS from StudyManager
163   _PTR(Study) study ( SalomeApp_Application::studyMgr()->GetStudyByName( (char*) theStudyName.latin1() ) );
164   if ( !study )
165     return false;
166
167   setStudyDS( study );
168
169   setRoot( new LightApp_RootObject( this ) ); // create myRoot
170
171   //SRN: BugID IPAL9021, put there the same code as in a method openDocument
172
173   // update loaded data models: call open() and update() on them.
174   ModelList dm_s;
175   dataModels( dm_s );
176
177   for ( ModelListIterator it( dm_s ); it.current(); ++it )
178     openDataModel( studyName(), it.current() );
179
180   // this will build a SUIT_DataObject-s tree under myRoot member field
181   // passing "false" in order NOT to rebuild existing data models' trees - it was done in previous step
182   // but tree that corresponds to not-loaded data models will be updated any way. 
183   ((SalomeApp_Application*)application())->updateObjectBrowser( false ); 
184
185   bool res = CAM_Study::openDocument( theStudyName );
186   emit opened( this );
187
188   bool restore = application()->resourceMgr()->booleanValue( "Study", "store_visual_state", true );
189   if ( restore ) {
190     std::vector<int> savePoints = getSavePoints();
191     if ( savePoints.size() > 0 )
192       SalomeApp_VisualState( (SalomeApp_Application*)application() ).restoreState( savePoints[savePoints.size()-1] );
193   }
194
195   //SRN: BugID IPAL9021: End
196
197   return res;
198 }
199
200 //=======================================================================
201 // name    : saveDocumentAs
202 /*! Purpose : Save document*/
203 //=======================================================================
204 bool SalomeApp_Study::saveDocumentAs( const QString& theFileName )
205 {
206   bool store = application()->resourceMgr()->booleanValue( "Study", "store_visual_state", true );
207   if ( store )
208     SalomeApp_VisualState( (SalomeApp_Application*)application() ).storeState();
209   
210   ModelList list; dataModels( list );
211
212   SalomeApp_DataModel* aModel = (SalomeApp_DataModel*)list.first();
213   QStringList listOfFiles;
214   for ( ; aModel; aModel = (SalomeApp_DataModel*)list.next() ) {
215     listOfFiles.clear();
216     aModel->saveAs( theFileName, this, listOfFiles );
217     if ( !listOfFiles.isEmpty() )
218       saveModuleData(aModel->module()->name(), listOfFiles);
219   }
220
221   // save SALOMEDS document
222   SUIT_ResourceMgr* resMgr = application()->resourceMgr();
223   if( !resMgr )
224     return false;
225
226   bool isMultiFile = resMgr->booleanValue( "Study", "multi_file", false ),
227        isAscii = resMgr->booleanValue( "Study", "ascii_file", false ),
228        res = isAscii ? 
229          SalomeApp_Application::studyMgr()->SaveAsASCII( theFileName.latin1(), studyDS(), isMultiFile ) :
230          SalomeApp_Application::studyMgr()->SaveAs     ( theFileName.latin1(), studyDS(), isMultiFile ) &&
231     CAM_Study::saveDocumentAs( theFileName ) &&  //SRN: BugID IPAL9377, removed usage of uninitialized variable <res>
232     saveStudyData(theFileName);
233
234   if ( res )
235     emit saved( this );
236
237   return res;
238 }
239
240 //=======================================================================
241 // name    : saveDocument
242 /*! Purpose : Save document*/
243 //=======================================================================
244 bool SalomeApp_Study::saveDocument()
245 {
246   bool store = application()->resourceMgr()->booleanValue( "Study", "store_visual_state", true );
247   if ( store )
248     SalomeApp_VisualState( (SalomeApp_Application*)application() ).storeState();
249
250   ModelList list; dataModels( list );
251
252   SalomeApp_DataModel* aModel = (SalomeApp_DataModel*)list.first();
253   QStringList listOfFiles;
254   for ( ; aModel; aModel = (SalomeApp_DataModel*)list.next() ) {
255     listOfFiles.clear();
256     aModel->save(listOfFiles);
257     if ( !listOfFiles.isEmpty() ) 
258       saveModuleData(aModel->module()->name(), listOfFiles);
259   }
260
261   // save SALOMEDS document
262   SUIT_ResourceMgr* resMgr = application()->resourceMgr();
263   if( !resMgr )
264     return false;
265
266   bool isMultiFile = resMgr->booleanValue( "Study", "multi_file", false ),
267        isAscii = resMgr->booleanValue( "Study", "ascii_file", false ),
268        res = isAscii ? 
269          SalomeApp_Application::studyMgr()->SaveASCII( studyDS(), isMultiFile ) :
270          SalomeApp_Application::studyMgr()->Save     ( studyDS(), isMultiFile ) && CAM_Study::saveDocument();
271
272   res = res && saveStudyData(studyName());
273   if ( res )
274     emit saved( this );  
275
276   return res;
277 }
278
279 //================================================================
280 // Function : closeDocument
281 /*! Purpose  : Close document*/
282 //================================================================
283 void SalomeApp_Study::closeDocument(bool permanently)
284 {
285   LightApp_Study::closeDocument(permanently);
286
287   // close SALOMEDS document
288   _PTR(Study) studyPtr = studyDS();
289   if ( studyPtr )
290   {
291     if(permanently) SalomeApp_Application::studyMgr()->Close( studyPtr );
292     SALOMEDSClient_Study* aStudy = 0;
293     setStudyDS( _PTR(Study)(aStudy) );
294   }
295 }
296
297 //================================================================
298 // Function : isModified
299 // Purpose  : 
300 //================================================================
301 bool SalomeApp_Study::isModified() const
302 {
303   bool isAnyChanged = studyDS() && studyDS()->IsModified();
304   if (!isAnyChanged)
305     isAnyChanged = LightApp_Study::isModified();
306
307   return isAnyChanged; 
308 }
309
310 //================================================================
311 // Function : isSaved
312 /*! Purpose  : Check: data model is saved?*/
313 //================================================================
314 bool SalomeApp_Study::isSaved() const
315 {
316   bool isAllSaved = studyDS() && studyDS()->GetPersistentReference().size();
317   if (!isAllSaved)
318     isAllSaved = LightApp_Study::isModified();
319
320   return isAllSaved; 
321 }
322
323 //=======================================================================
324 // name    : saveModuleData
325 /*! Purpose : save list file for module 'theModuleName' */
326 //=======================================================================
327 void SalomeApp_Study::saveModuleData( QString theModuleName, QStringList theListOfFiles )
328 {
329   int aNb = theListOfFiles.count();
330   if ( aNb == 0 )
331     return;
332
333   std::vector<std::string> aListOfFiles ( aNb );
334   int anIndex = 0;
335   for ( QStringList::Iterator it = theListOfFiles.begin(); it != theListOfFiles.end(); ++it ) {
336     if ( (*it).isEmpty() )
337       continue;
338     aListOfFiles[anIndex] = (*it).latin1();
339     anIndex++;
340   }
341   SetListOfFiles(theModuleName, aListOfFiles);
342 }
343
344 //=======================================================================
345 // name    : openModuleData
346 /*! Purpose : gets list of file for module 'theModuleNam' */
347 //=======================================================================
348 void SalomeApp_Study::openModuleData( QString theModuleName, QStringList& theListOfFiles )
349 {
350   std::vector<std::string> aListOfFiles =  GetListOfFiles( theModuleName );
351
352   int i, aLength = aListOfFiles.size() - 1;
353   if ( aLength < 0 )
354     return;
355
356   //Get a temporary directory for saved a file
357   theListOfFiles.append(aListOfFiles[0].c_str());
358
359   for(i = 0; i < aLength; i++)
360     theListOfFiles.append(aListOfFiles[i+1].c_str());
361 }
362
363 //=======================================================================
364 // name    : saveStudyData
365 /*! Purpose : save data from study */
366 //=======================================================================
367 bool SalomeApp_Study::saveStudyData( const QString& theFileName )
368 {
369   ModelList list; dataModels( list );
370   SalomeApp_DataModel* aModel = (SalomeApp_DataModel*)list.first();
371   std::vector<std::string> listOfFiles(0);
372   for ( ; aModel; aModel = (SalomeApp_DataModel*)list.next() )
373     SetListOfFiles(aModel->module()->name(), listOfFiles);
374   return true;
375 }
376
377 //=======================================================================
378 // name    : openStudyData
379 /*! Purpose : open data for study */
380 //=======================================================================
381 bool SalomeApp_Study::openStudyData( const QString& theFileName )
382 {
383  return true;
384 }
385
386 /*!
387   Set studyDS.
388 */
389 void SalomeApp_Study::setStudyDS( const _PTR(Study)& s )
390 {
391   myStudyDS = s;
392 }
393
394 /*!
395   Insert data model.
396 */
397 void SalomeApp_Study::dataModelInserted (const CAM_DataModel* dm)
398 {
399   MESSAGE("SalomeApp_Study::dataModelInserted() : module name() = " << dm->module()->name());
400
401   CAM_Study::dataModelInserted(dm);
402
403   //  addComponent(dm);
404 }
405
406 /*!
407  Create SComponent for module, using default engine (CORBAless)
408 */
409 void SalomeApp_Study::addComponent(const CAM_DataModel* dm)
410 {
411   SalomeApp_Module* aModule = dynamic_cast<SalomeApp_Module*>( dm->module() );
412   // 1. aModule == 0 means that this is a light module (no CORBA enigine)
413   if (!aModule) {
414     // Check SComponent existance
415     _PTR(Study) aStudy = studyDS();
416     if (!aStudy) 
417       return;
418     _PTR(SComponent) aComp = aStudy->FindComponent(dm->module()->name());
419     if (!aComp) {
420       // Create SComponent
421       _PTR(StudyBuilder) aBuilder = aStudy->NewBuilder();
422       aComp = aBuilder->NewComponent(dm->module()->name());
423       aBuilder->SetName(aComp, dm->module()->moduleName().latin1());
424       QString anIconName = dm->module()->iconName();
425       if (!anIconName.isEmpty()) {
426         _PTR(AttributePixMap) anAttr = aBuilder->FindOrCreateAttribute(aComp, "AttributePixMap");
427         if (anAttr)
428           anAttr->SetPixMap(anIconName.latin1());
429       }
430       // Set default engine IOR
431       aBuilder->DefineComponentInstance(aComp, SalomeApp_Application::defaultEngineIOR().latin1());
432       //SalomeApp_DataModel::BuildTree( aComp, root(), this, /*skipExisitng=*/true );
433       SalomeApp_DataModel::synchronize( aComp, this );
434     }
435   }
436 }
437
438 /*!
439   Open data model
440 */
441 bool SalomeApp_Study::openDataModel( const QString& studyName, CAM_DataModel* dm )
442 {
443   if (!dm)
444     return false;
445
446   //  SalomeApp_DataModel* aDM = (SalomeApp_DataModel*)(dm);
447   SalomeApp_Module* aModule = dynamic_cast<SalomeApp_Module*>( dm->module() );
448   _PTR(Study)       aStudy = studyDS(); // shared_ptr cannot be used here
449   _PTR(SComponent)  aSComp;
450   QString anEngine;
451   // 1. aModule == 0 means that this is a light module (no CORBA enigine)
452   if (!aModule) {
453     anEngine = SalomeApp_Application::defaultEngineIOR();
454     aSComp = aStudy->FindComponent(dm->module()->name());
455   }
456   else {
457     SalomeApp_DataModel* aDM = dynamic_cast<SalomeApp_DataModel*>( dm );
458     if ( aDM ) {
459       QString anId = aDM->getRootEntry( this );
460       if ( anId.isEmpty() )
461         return true; // Probably nothing to load
462       anEngine = aDM->getModule()->engineIOR();
463       if ( anEngine.isEmpty() )
464         return false;
465       aSComp = aStudy->FindComponentID( std::string( anId.latin1() ) );
466     }
467   }
468   if ( aSComp ) {
469     _PTR(StudyBuilder) aBuilder( aStudy->NewBuilder() );
470     if ( aBuilder ) {
471       try {
472         aBuilder->LoadWith( aSComp, std::string( anEngine.latin1() ) );
473       }
474       catch( const SALOME::SALOME_Exception& ) {
475         // Oops, something went wrong while loading -> return an error
476         return false;
477       }
478       // Something has been read -> create data model tree
479       //SalomeApp_DataModel* aDM = dynamic_cast<SalomeApp_DataModel*>( dm );
480       // aDM->buildTree( aSComp, 0, this );
481     }
482   } else {
483     // Don't return false here, for there might be no data
484     // for a given component in the study yet
485   }
486   QStringList listOfFiles;
487   openModuleData(dm->module()->name(), listOfFiles);
488   if (dm && dm->open(studyName, this, listOfFiles)) {
489     // Remove the files and temporary directory, created
490     // for this module by LightApp_Engine_i::Load()
491     bool isMultiFile = false; // TODO: decide, how to access this parameter
492     RemoveTemporaryFiles( dm->module()->name(), isMultiFile );
493
494     // Something has been read -> create data model tree
495     LightApp_DataModel* aDM = dynamic_cast<LightApp_DataModel*>( dm );
496     if ( aDM )
497       aDM->update(NULL, this);
498     return true;
499   }
500   return false;
501 }
502
503 /*!
504   Create new study name.
505 */
506 QString SalomeApp_Study::newStudyName() const
507 {
508   std::vector<std::string> studies = SalomeApp_Application::studyMgr()->GetOpenStudies();
509   QString prefix( "Study%1" ), newName, curName;
510   int i = 1, j, n = studies.size();
511   while ( newName.isEmpty() ){
512     curName = prefix.arg( i );
513     for ( j = 0 ; j < n; j++ ){
514       if ( !strcmp( studies[j].c_str(), curName.latin1() ) )
515         break;
516     }
517     if ( j == n )
518       newName = curName;
519     else
520       i++;
521   }
522   return newName;
523 }
524
525 //================================================================
526 // Function : GetListOfFiles
527 /*! Purpose  : to be used by CORBAless modules*/
528 //================================================================
529 std::vector<std::string> SalomeApp_Study::GetListOfFiles( const char* theModuleName  ) const
530 {
531   SalomeApp_Engine_i* aDefaultEngine = SalomeApp_Engine_i::GetInstance();
532   if (aDefaultEngine)
533     return aDefaultEngine->GetListOfFiles(id(), theModuleName);
534
535   std::vector<std::string> aListOfFiles;
536   return aListOfFiles;
537 }
538
539 //================================================================
540 // Function : SetListOfFiles
541 /*! Purpose  : to be used by CORBAless modules*/
542 //================================================================
543 void SalomeApp_Study::SetListOfFiles ( const char* theModuleName,
544                                        const std::vector<std::string> theListOfFiles )
545 {
546   SalomeApp_Engine_i* aDefaultEngine = SalomeApp_Engine_i::GetInstance();
547   if (aDefaultEngine)
548     aDefaultEngine->SetListOfFiles(theListOfFiles, id(), theModuleName);
549 }
550
551 //================================================================
552 // Function : GetTmpDir
553 /*! Purpose  : to be used by CORBAless modules*/
554 //================================================================
555 std::string SalomeApp_Study::GetTmpDir ( const char* theURL, const bool  isMultiFile )
556 {
557   std::string anURLDir = SALOMEDS_Tool::GetDirFromPath(theURL);
558   std::string aTmpDir = isMultiFile ? anURLDir : SALOMEDS_Tool::GetTmpDir();
559   return aTmpDir;
560 }
561
562 //================================================================
563 // Function : RemoveTemporaryFiles
564 /*! Purpose  : to be used by CORBAless modules*/
565 //================================================================
566 void SalomeApp_Study::RemoveTemporaryFiles ( const char* theModuleName, const bool isMultiFile ) const
567 {
568   if (isMultiFile)
569     return;
570
571   std::vector<std::string> aListOfFiles = GetListOfFiles( theModuleName );
572   if (aListOfFiles.size() > 0) {
573     std::string aTmpDir = aListOfFiles[0];
574
575     const int n = aListOfFiles.size() - 1;
576     SALOMEDS::ListOfFileNames_var aSeq = new SALOMEDS::ListOfFileNames;
577     aSeq->length(n);
578     for (int i = 0; i < n; i++)
579       aSeq[i] = CORBA::string_dup(aListOfFiles[i + 1].c_str());
580
581     SALOMEDS_Tool::RemoveTemporaryFiles(aTmpDir.c_str(), aSeq.in(), true);
582   }
583 }
584
585 // END: methods to be used by CORBAless modules
586
587 void SalomeApp_Study::deleteReferencesTo( _PTR( SObject ) obj )
588 {
589   _PTR(StudyBuilder) sb = studyDS()->NewBuilder();
590   std::vector<_PTR(SObject)> aRefs = studyDS()->FindDependances( obj );
591   for( int i=0, n=aRefs.size(); i<n; i++ )
592   {
593     _PTR( SObject ) o = aRefs[i];
594     if( o->GetFatherComponent()->ComponentDataType()==obj->GetFatherComponent()->ComponentDataType() )
595     {
596       sb->RemoveReference( o );
597       sb->RemoveObjectWithChildren( o );
598     }
599   }
600 }
601
602 //================================================================
603 // Function : referencedToEntry
604 /*! Purpose  : Return referenced entry from entry*/
605 //================================================================
606 QString SalomeApp_Study::referencedToEntry( const QString& entry ) const
607 {
608   _PTR(SObject) obj = studyDS()->FindObjectID( entry.latin1() );
609   _PTR(SObject) refobj;
610
611   if( obj && obj->ReferencedObject( refobj ) )
612     return refobj->GetID().c_str();
613   return LightApp_Study::referencedToEntry( entry );
614 }
615
616 //================================================================
617 // Function : componentDataType
618 /*! Purpose  : Return component data type from entry*/
619 //================================================================
620 QString SalomeApp_Study::componentDataType( const QString& entry ) const
621 {
622   _PTR(SObject) obj( studyDS()->FindObjectID( entry.latin1() ) );
623   if ( !obj )
624     return LightApp_Study::componentDataType( entry );
625   return obj->GetFatherComponent()->ComponentDataType().c_str();
626 }
627
628 //================================================================
629 // Function : componentDataType
630 /*! Purpose  : Return component data type from entry*/
631 //================================================================
632 bool SalomeApp_Study::isComponent( const QString& entry ) const
633 {
634   _PTR(SObject) obj( studyDS()->FindObjectID( entry.latin1() ) );
635   return obj && QString( obj->GetID().c_str() ) == obj->GetFatherComponent()->GetID().c_str();
636 }
637
638 //================================================================
639 // Function : children
640 /*! Purpose : Return entries of children of object*/
641 //================================================================
642 void SalomeApp_Study::children( const QString& entry, QStringList& child_entries ) const
643 {
644   _PTR(SObject) SO = studyDS()->FindObjectID( entry.latin1() );
645   _PTR(ChildIterator) anIter ( studyDS()->NewChildIterator( SO ) );
646   anIter->InitEx( true );
647   while( anIter->More() )
648   {
649     _PTR(SObject) val( anIter->Value() );
650     child_entries.append( val->GetID().c_str() );
651     anIter->Next();
652   }
653 }
654
655 void SalomeApp_Study::components( QStringList& comps ) const
656 {
657   for( _PTR(SComponentIterator) it ( studyDS()->NewComponentIterator() ); it->More(); it->Next() ) 
658   {
659     _PTR(SComponent) aComponent ( it->Value() );
660     if( aComponent && aComponent->ComponentDataType() == "Interface Applicative" )
661       continue; // skip the magic "Interface Applicative" component
662     comps.append( aComponent->ComponentDataType().c_str() );
663   }
664 }
665
666 //================================================================
667 // Function : getSavePoints
668 /*! Purpose : returns a list of saved points' IDs
669 */
670 //================================================================
671 std::vector<int> SalomeApp_Study::getSavePoints()
672 {
673   std::vector<int> v;
674
675   _PTR(SObject) so = studyDS()->FindComponent("Interface Applicative");
676   if(!so) return v;
677
678   _PTR(StudyBuilder) builder = studyDS()->NewBuilder();
679   _PTR(ChildIterator) anIter ( studyDS()->NewChildIterator( so ) );
680   for(; anIter->More(); anIter->Next())
681   {
682     _PTR(SObject) val( anIter->Value() );
683     _PTR(GenericAttribute) genAttr;
684     if(builder->FindAttribute(val, genAttr, "AttributeParameter")) v.push_back(val->Tag());
685   }
686
687   return v;
688 }
689
690 //================================================================
691 // Function :removeSavePoint
692 /*! Purpose : remove a given save point
693 */
694 //================================================================
695 void SalomeApp_Study::removeSavePoint(int savePoint)
696 {
697   if(savePoint <= 0) return;
698  _PTR(AttributeParameter) AP = studyDS()->GetCommonParameters(getVisualComponentName(), savePoint);
699   _PTR(SObject) so = AP->GetSObject();
700   _PTR(StudyBuilder) builder = studyDS()->NewBuilder();
701   builder->RemoveObjectWithChildren(so);
702 }
703
704 //================================================================
705 // Function : getNameOfSavePoint
706 /*! Purpose : returns a name of save point
707 */
708 //================================================================
709 QString SalomeApp_Study::getNameOfSavePoint(int savePoint)
710 {
711   _PTR(AttributeParameter) AP = studyDS()->GetCommonParameters(getVisualComponentName(), savePoint);
712   SALOMEDS_IParameters ip(AP);
713   return ip.getProperty("AP_SAVEPOINT_NAME");
714 }
715
716 //================================================================
717 // Function : setNameOfSavePoint
718 /*! Purpose : sets a name of save point
719 */
720 //================================================================
721 void SalomeApp_Study::setNameOfSavePoint(int savePoint, const QString& nameOfSavePoint)
722 {
723   _PTR(AttributeParameter) AP = studyDS()->GetCommonParameters(getVisualComponentName(), savePoint);
724   SALOMEDS_IParameters ip(AP);
725   ip.setProperty("AP_SAVEPOINT_NAME", nameOfSavePoint.latin1());
726 }
727
728 //================================================================
729 // Function : getVisualComponentName
730 /*! Purpose : returns a name of the component where visual
731  *             parameters are stored
732 */
733 //================================================================
734 std::string SalomeApp_Study::getVisualComponentName()
735 {
736   return "Interface Applicative";
737 }
738
739 //================================================================
740 // Function : updateModelRoot
741 /*! Purpose : slot called on change of a root of a data model. redefined from CAM_Study*/
742 //================================================================
743 void SalomeApp_Study::updateModelRoot( const CAM_DataModel* dm )
744 {
745   LightApp_Study::updateModelRoot( dm );
746
747   // calling updateSavePointDataObjects in order to set correct order of "Gui states" object
748   // it must always be the last one.
749   ((SalomeApp_Application*)application())->updateSavePointDataObjects( this );
750 }