]> SALOME platform Git repositories - modules/gui.git/blob - src/SalomeApp/SalomeApp_DataModel.cxx
Salome HOME
Update comments
[modules/gui.git] / src / SalomeApp / SalomeApp_DataModel.cxx
1 // File:      SalomeApp_DataModel.cxx
2 // Created:   10/25/2004 10:36:06 AM
3 // Author:    Sergey LITONIN
4 // Copyright (C) CEA 2004
5
6 #include "SalomeApp_DataModel.h"
7 #include "SalomeApp_Study.h"
8 #include "SalomeApp_RootObject.h"
9 #include "SalomeApp_DataObject.h"
10 #include "SalomeApp_Module.h"
11 #include "SalomeApp_Application.h"
12 #include "SalomeApp_SelectionMgr.h"
13 #include "SalomeApp_Engine_i.hxx"
14
15 #include <CAM_DataObject.h>
16
17 #include <SUIT_Application.h>
18 #include <SUIT_ResourceMgr.h>
19 #include <SUIT_Session.h>
20
21 #include "SALOMEDS_Tool.hxx"
22
23 #include <SALOMEconfig.h>
24 #include CORBA_SERVER_HEADER(SALOME_Exception)
25
26 //=======================================================================
27 // name    : BuildTree
28 /*!Purpose : static method used by SalomeApp_Study and SalomeApp_DataModel classes
29  *           to create default SALOMEDS-based data object tree
30  */
31 //=======================================================================
32 SUIT_DataObject* SalomeApp_DataModel::BuildTree( const _PTR(SObject)& obj,
33                                                  SUIT_DataObject* parent,
34                                                  SalomeApp_Study* study,
35                                                  bool skip  )
36 {
37   SalomeApp_DataObject* aDataObj = 0;
38   if ( !obj || !study )
39     return aDataObj;
40
41   _PTR(SObject) refObj;
42   if ( obj->GetName().size() || obj->ReferencedObject( refObj ) )  // skip nameless non references SObjects
43   {
44     _PTR(SComponent) aSComp( obj );
45
46     // patch for bug IPAL9313
47     if ( aSComp && parent && skip ) 
48     {
49       QString aSName( aSComp->GetName().c_str() );
50       DataObjectList allComponents = parent->children( /*recursive=*/false );
51       for ( DataObjectListIterator it( allComponents ); it.current(); ++it ) {
52         SUIT_DataObject* componentObj = it.current();
53         if ( componentObj->name() == aSName ) {
54           //mkr : modifications for update already published in 
55           //object browser, but not loaded yet component
56           //get names list of loaded modules
57           QStringList aLoadedModNames;
58           CAM_Application* anApp = dynamic_cast<CAM_Application*>( SUIT_Session::session()->activeApplication() );
59           if ( anApp ) anApp->modules( aLoadedModNames, /*loaded*/true );
60           if ( !aLoadedModNames.isEmpty() && aLoadedModNames.contains( aSName ) == 0 ) {
61             // delete DataObject and re-create it and all its sub-objects
62             delete componentObj;
63             // don't do anything here, because iterator may be corrupted (deleted object inside it)
64             break;
65           }
66           else
67             return componentObj;
68         }
69       }
70     }
71
72     aDataObj = aSComp ? new SalomeApp_ModuleObject( aSComp, parent ) :
73                         new SalomeApp_DataObject  ( obj, parent );
74
75     _PTR(ChildIterator) it ( study->studyDS()->NewChildIterator( obj ) );
76     for ( ; it->More();it->Next() ) {
77       // don't use shared_ptr here, for Data Object will take
78       // ownership of this pointer
79       _PTR(SObject) aSO( it->Value() );
80       BuildTree( aSO, aDataObj, study );
81     }
82   }
83   return aDataObj;
84 }
85
86 //=======================================================================
87 // name    : SalomeApp_DataModel::SalomeApp_DataModel
88 /*!Purpose : Constructor*/
89 //=======================================================================
90 SalomeApp_DataModel::SalomeApp_DataModel( CAM_Module* theModule )
91 : CAM_DataModel( theModule )
92 {
93 }
94
95 //=======================================================================
96 // name    : SalomeApp_DataModel::~SalomeApp_DataModel
97 /*! Purpose : Destructor*/
98 //=======================================================================
99 SalomeApp_DataModel::~SalomeApp_DataModel()
100 {
101 }
102
103 //================================================================
104 // Function : open
105 /*! Purpose  : Open data model*/
106 //================================================================
107 bool SalomeApp_DataModel::open( const QString&, CAM_Study* study )
108 {
109   SalomeApp_Study* aDoc = dynamic_cast<SalomeApp_Study*>( study );
110   if ( !aDoc )
111     return false;
112
113   QString anId = getRootEntry( aDoc );
114   if ( anId.isEmpty() )
115     return true; // Probably nothing to load
116
117   QString anEngine = getModule()->engineIOR();
118   if ( anEngine == "-1" ) {
119     // Module doesn't have a CORBA engine and doesn't use
120     // a default one -> SALOMEDS persistence cannot be used
121     return false;
122   }
123
124   if ( anEngine.isEmpty() ) {
125     // Module use a default engine
126     //TODO: deside, if the below code has to be copyed in a light data model to avoid bulding of data tree twice
127     anEngine = SalomeApp_Application::defaultEngineIOR();
128   }
129
130   _PTR(Study)      aStudy ( aDoc->studyDS() ); // shared_ptr cannot be used here
131   _PTR(SComponent) aSComp ( aStudy->FindComponentID( std::string( anId.latin1() ) ) );
132
133   if ( aSComp ) {
134     _PTR(StudyBuilder) aBuilder( aStudy->NewBuilder() );
135     if ( aBuilder ) {
136       try {
137         aBuilder->LoadWith( aSComp, std::string( anEngine.latin1() ) );
138       }
139       catch( const SALOME::SALOME_Exception& ) {
140         // Oops, something went wrong while loading -> return an error
141         return false;
142       }
143
144       // Something has been read -> create data model tree
145       buildTree( aSComp, 0, aDoc );
146     }
147   } else {
148     // Don't return false here, for there might be no data
149     // for a given component in the study yet
150   }
151
152   emit opened(); //TODO: is it really needed? to be removed maybe...
153   return true;
154 }
155
156 //================================================================
157 // Function : save
158 /*! Purpose  : Emit saved()*/
159 //================================================================
160 bool SalomeApp_DataModel::save()
161 {
162   emit saved();
163   return true;
164 }
165
166 //================================================================
167 // Function : saveAs
168 /*! Purpose  : Emit saved() */
169 //================================================================
170 bool SalomeApp_DataModel::saveAs( const QString&, CAM_Study* )
171 {
172   emit saved();
173   return true;
174 }
175
176 //================================================================
177 // Function : close
178 /*! Purpose  : Emit closed()*/
179 //================================================================
180 bool SalomeApp_DataModel::close()
181 {
182   emit closed();
183   return true;
184 }
185
186 //================================================================
187 // Function : update
188 /*! Purpose  : Update application.*/
189 //================================================================
190 void SalomeApp_DataModel::update( SalomeApp_DataObject*, SalomeApp_Study* study )
191 {
192   SalomeApp_RootObject* studyRoot = 0;
193   _PTR(SObject) sobj;
194   SalomeApp_DataObject* modelRoot = dynamic_cast<SalomeApp_DataObject*>( root() );
195   if ( !modelRoot ){ // not yet connected to a study -> try using <study> argument
196     if ( !study )
197       study = dynamic_cast<SalomeApp_Study*>( getModule()->getApp()->activeStudy() );
198
199     if ( study ){
200       studyRoot = dynamic_cast<SalomeApp_RootObject*>( study->root() );
201       QString anId = getRootEntry( study );
202       if ( !anId.isEmpty() ){ // if nothing is published in the study for this module -> do nothing
203         _PTR(Study) aStudy ( study->studyDS() );
204         sobj = aStudy->FindComponentID( std::string( anId.latin1() ) );
205       }
206     }
207   }
208   else{
209     studyRoot = dynamic_cast<SalomeApp_RootObject*>( modelRoot->root() );
210     study = studyRoot->study(); // <study> value should not change here theoretically, but just to make sure
211     _PTR(Study) aStudy ( study->studyDS() );
212
213     // modelRoot->object() cannot be reused here: it is about to be deleted by buildTree() soon
214     sobj = aStudy->FindComponentID( std::string( modelRoot->entry().latin1() ) );
215   }
216   buildTree( sobj, studyRoot, study );
217 }
218
219 //================================================================
220 // Function : buildTree
221 /*! Purpose  : private method, build tree.*/
222 //================================================================
223 void SalomeApp_DataModel::buildTree( const _PTR(SObject)& obj,
224                                      SUIT_DataObject* parent,
225                                      SalomeApp_Study* study )
226 {
227   if ( !obj )
228     return;
229   //if ( !root() ){ // Build default SALOMEDS-based data object tree and insert it into study
230     SalomeApp_ModuleObject* aNewRoot = dynamic_cast<SalomeApp_ModuleObject*>( BuildTree( obj, parent, study ) );
231     if ( aNewRoot ){
232       aNewRoot->setDataModel( this );
233       setRoot( aNewRoot );
234     }
235     //}
236 }
237
238 //================================================================
239 // Function : getModule
240 /*! Purpose  : gets module*/
241 //================================================================
242
243 SalomeApp_Module* SalomeApp_DataModel::getModule() const
244 {
245   return dynamic_cast<SalomeApp_Module*>( module() );
246 }
247
248 //================================================================
249 // Function : getStudy
250 /*! Purpose  : gets study */
251 //================================================================
252 SalomeApp_Study* SalomeApp_DataModel::getStudy() const
253 {
254   SalomeApp_RootObject* aRoot = dynamic_cast<SalomeApp_RootObject*>( root()->root() );
255   if ( !aRoot )
256     return 0;
257   return aRoot->study();
258 }
259
260 //================================================================
261 // Function : getRootEntry
262 /*! Purpose  : returns study entry corresponding to this data model*/
263 //================================================================
264 QString SalomeApp_DataModel::getRootEntry( SalomeApp_Study* study ) const
265 {
266   QString anEntry;
267   if ( root() && root()->root() ) { // data model already in a study
268     SalomeApp_DataObject* anObj = dynamic_cast<SalomeApp_DataObject*>( root() );
269     if ( anObj )
270       anEntry = anObj->entry();
271   }
272   else if ( study && study->studyDS() ) { // this works even if <myRoot> is null
273     _PTR(SComponent) aSComp( study->studyDS()->FindComponent( module()->name() ) );
274     if ( aSComp )
275       anEntry = aSComp->GetID().c_str();
276   }
277   return anEntry;
278 }
279
280 //================================================================
281 // Function : isModified
282 /*! Purpose  : default implementation, always returns false so as not to mask study's isModified()*/
283 //================================================================
284 bool SalomeApp_DataModel::isModified() const
285 {
286   return false;
287 }
288
289 //================================================================
290 // Function : isSaved
291 /*! Purpose  : default implementation, always returns true so as not to mask study's isSaved()*/
292 //================================================================
293 bool SalomeApp_DataModel::isSaved() const
294 {
295   return true;
296 }
297
298 // BEGIN: methods to be used by CORBAless modules
299
300 //================================================================
301 // Function : GetListOfFiles
302 /*! Purpose  : to be used by CORBAless modules*/
303 //================================================================
304 std::vector<std::string> SalomeApp_DataModel::GetListOfFiles() const
305        //(const int theStudyId, const char* theComponentName) const
306 {
307   SUIT_Study* anActiveStudy = getModule()->getApp()->activeStudy();
308   if (anActiveStudy) {
309     int aStudyId = anActiveStudy->id();
310     SalomeApp_Engine_i* aDefaultEngine = SalomeApp_Engine_i::GetInstance();
311     if (aDefaultEngine) {
312       return aDefaultEngine->GetListOfFiles(aStudyId, module()->name());
313     }
314   }
315
316   std::vector<std::string> aListOfFiles;
317   return aListOfFiles;
318 }
319
320 //================================================================
321 // Function : SetListOfFiles
322 /*! Purpose  : to be used by CORBAless modules*/
323 //================================================================
324 void SalomeApp_DataModel::SetListOfFiles (const std::vector<std::string> theListOfFiles)
325      //(const std::vector<std::string> theListOfFiles,
326      // const int                      theStudyId,
327      // const char*                    theComponentName)
328 {
329   SUIT_Study* anActiveStudy = getModule()->getApp()->activeStudy();
330   if (anActiveStudy) {
331     int aStudyId = anActiveStudy->id();
332     SalomeApp_Engine_i* aDefaultEngine = SalomeApp_Engine_i::GetInstance();
333     if (aDefaultEngine) {
334       aDefaultEngine->SetListOfFiles(theListOfFiles, aStudyId, module()->name());
335     }
336   }
337 }
338
339 //================================================================
340 // Function : GetTmpDir
341 /*! Purpose  : Static method. To be used by CORBAless modules*/
342 //================================================================
343 std::string SalomeApp_DataModel::GetTmpDir (const char* theURL,
344                                             const bool  isMultiFile)
345 {
346   std::string anURLDir = SALOMEDS_Tool::GetDirFromPath(theURL);
347   std::string aTmpDir = isMultiFile ? anURLDir : SALOMEDS_Tool::GetTmpDir();
348   return aTmpDir;
349 }
350
351 //================================================================
352 // Function : RemoveTemporaryFiles
353 /*! Purpose  : to be used by CORBAless modules*/
354 //================================================================
355 void SalomeApp_DataModel::RemoveTemporaryFiles (const bool isMultiFile) const
356 {
357   if (isMultiFile)
358     return;
359
360   std::vector<std::string> aListOfFiles = GetListOfFiles();
361   if (aListOfFiles.size() > 0) {
362     std::string aTmpDir = aListOfFiles[0];
363
364     const int n = aListOfFiles.size() - 1;
365     SALOMEDS::ListOfFileNames_var aSeq = new SALOMEDS::ListOfFileNames;
366     aSeq->length(n);
367     for (int i = 0; i < n; i++)
368       aSeq[i] = CORBA::string_dup(aListOfFiles[i + 1].c_str());
369
370     SALOMEDS_Tool::RemoveTemporaryFiles(aTmpDir.c_str(), aSeq.in(), true);
371   }
372 }
373
374 // END: methods to be used by CORBAless modules