Salome HOME
Merge from BR_PARAVIS_LOT1_2 24/02/2010
[modules/paravis.git] / src / PVGUI / PARAVIS_Gen_i.cc
1 //  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
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.
10 //
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.
15 //
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
19 //
20 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 //  PARAVIS OBJECT : interactive object for PARAVIS entities implementation
23 //  File   : PARAVIS_Gen_i.cc
24 //  Author : Vitaly Smetannikov
25 //  Module : PARAVIS
26 //
27
28
29 #include "PARAVIS_Gen_i.hh"
30
31 // IDL Headers
32 #include <omnithread.h>
33 #include CORBA_SERVER_HEADER(SALOME_Session)
34 #include CORBA_SERVER_HEADER(SALOME_ModuleCatalog)
35
36 #include <CAM_Module.h>
37 #include "PVGUI_Module.h"
38 #include <SalomeApp_Application.h>
39 #include <SUIT_ResourceMgr.h>
40
41 #include <SALOMEDS_Tool.hxx>
42 #include <QFileInfo>
43
44 #include "PV_Events.h"
45 #include "PV_Tools.h"
46
47 #include "QDomDocument"
48 #include "QDomNode"
49 #include "QDomElement"
50 #include "QFile"
51 #include "QDir"
52 #include "QTextStream"
53
54 #include "vtkWrapIDL.h"
55
56 #include <pqServer.h>
57 #include <pqServerResource.h>
58
59
60 #ifdef _DEBUG_
61 static int MYDEBUG = 1;
62 #else
63 static int MYDEBUG = 0;
64 #endif
65
66 using namespace std;
67
68 extern PARAVIS::PARAVIS_Base_i* CreateInstance(::vtkObjectBase* Inst, const QString&);
69
70 extern "C" 
71 PARAVIS_I_EXPORT PARAVIS::PARAVIS_Gen_ptr GetImpl(CORBA::ORB_ptr theORB, 
72                                                   PortableServer::POA_ptr thePOA,
73                                                   SALOME_NamingService* theNamingService,
74                                                   QMutex* theMutex)
75 {
76   if(MYDEBUG) MESSAGE("extern 'C' GetImpl");
77   PARAVIS::PARAVIS_Gen_i *aPARAVIS_Gen = new PARAVIS::PARAVIS_Gen_i(theORB, 
78                                                                     thePOA, 
79                                                                     theNamingService, 
80                                                                     theMutex);
81   return aPARAVIS_Gen->_this();
82 }
83
84
85
86 namespace PARAVIS
87 {
88   PARAVIS_Base_i::~PARAVIS_Base_i() {
89     if(mySmartPointer != NULL) mySmartPointer->Delete();
90   }
91
92   void PARAVIS_Base_i::Init(::vtkObjectBase* base) {
93     if (mySmartPointer != NULL) mySmartPointer->Delete();
94     mySmartPointer = base;
95   }
96
97   ::vtkObjectBase* PARAVIS_Base_i::getVTKObject(PARAVIS_Base_ptr theBase) {
98     PARAVIS_Base_i* aBase = GET_SERVANT(theBase);
99     return (aBase != NULL)? aBase->getVTKObject() : NULL;
100   }
101
102   CORBA::Boolean PARAVIS_Base_i::IsSame(PARAVIS_Base_ptr theOther)
103   {
104     PARAVIS_Base_i* aBase = GET_SERVANT(theOther);
105     if (aBase == NULL) 
106       return false;
107     return mySmartPointer.GetPointer() == aBase->getVTKObject();
108   }
109
110
111
112
113   PARAVIS_Gen_i*          PARAVIS_Gen_i::myParavisGenImpl;
114   CORBA::ORB_var          PARAVIS_Gen_i::myOrb;
115   PortableServer::POA_var PARAVIS_Gen_i::myPoa;
116   SALOME_LifeCycleCORBA*  PARAVIS_Gen_i::myEnginesLifeCycle;
117   SALOME_NamingService*   PARAVIS_Gen_i::myNamingService;
118   QMutex*                 PARAVIS_Gen_i::myMutex;
119   SalomeApp_Application*  PARAVIS_Gen_i::mySalomeApp = 0;
120
121
122   //----------------------------------------------------------------------------
123   PARAVIS_Gen_i::PARAVIS_Gen_i(CORBA::ORB_ptr theORB, PortableServer::POA_ptr thePOA,
124                                SALOME_NamingService* theNamingService, QMutex* theMutex) :
125     Engines_Component_i()
126   {
127     if(MYDEBUG) MESSAGE("PARAVIS_Gen_i::PARAVIS_Gen_i");
128     if (mySalomeApp) return;
129
130     myMutex = theMutex;
131     myOrb = CORBA::ORB::_duplicate(theORB);
132     myPoa = PortableServer::POA::_duplicate(thePOA);
133     myParavisGenImpl = this;
134     myNamingService = theNamingService;
135
136     static SALOME_LifeCycleCORBA aEnginesLifeCycle(theNamingService);
137     myEnginesLifeCycle = &aEnginesLifeCycle;
138
139     CORBA::Object_var anObj = myNamingService->Resolve("/myStudyManager");
140     if (!CORBA::is_nil(anObj)) {
141       SALOMEDS::StudyManager_var aStudyManager = SALOMEDS::StudyManager::_narrow(anObj);
142       SALOMEDS::ListOfOpenStudies_var aListOfOpenStudies = aStudyManager->GetOpenStudies();
143       if(aListOfOpenStudies->length() > 0) {
144         CORBA::String_var aStudyName = aListOfOpenStudies[0];
145         myStudyDocument = aStudyManager->GetStudyByName(aStudyName);
146         if (!myStudyDocument->_is_nil()) {
147           mySalomeApp = ProcessEvent(new TGetGUIApplication(myStudyDocument->StudyId()));
148           if(!myStudyDocument->GetProperties()->IsLocked())
149             FindOrCreateParaVisComponent(myStudyDocument);
150         }
151       } else
152         if(MYDEBUG) MESSAGE("PARAVIS_Gen_i::PARAVIS_Gen_i : there is no opened study in StudyManager !!!");
153     } else
154       if(MYDEBUG) MESSAGE("PARAVIS_Gen_i::PARAVIS_Gen_i : Can't find StudyManager !!!");
155
156   }
157
158   //----------------------------------------------------------------------------
159   PARAVIS_Gen_i::~PARAVIS_Gen_i()
160   {
161     if(MYDEBUG) MESSAGE("PARAVIS_Gen_i::~PARAVIS_Gen_i");
162   }
163
164   //----------------------------------------------------------------------------
165   char* PARAVIS_Gen_i::GetIOR()
166   {
167     if(myIOR == ""){
168       CORBA::Object_var anObject = _this();
169       CORBA::String_var anIOR = myOrb->object_to_string(anObject);
170       myIOR = anIOR.in();
171     }
172     return CORBA::string_dup(myIOR.c_str());
173   }
174
175   //----------------------------------------------------------------------------
176   void PARAVIS_Gen_i::ImportFile(const char* theFileName)
177   {
178     if(MYDEBUG) MESSAGE("PARAVIS_Gen_i::ImportFile: " <<theFileName);
179     ProcessVoidEvent(new TImportFile(mySalomeApp, theFileName));
180   }
181
182   //----------------------------------------------------------------------------
183   char* PARAVIS_Gen_i::GetTrace()
184   {
185     if(MYDEBUG) MESSAGE("PARAVIS_Gen_i::PrintTrace: ");
186     return CORBA::string_dup(ProcessEvent(new TGetTrace(mySalomeApp)).c_str());
187   }
188
189   //----------------------------------------------------------------------------
190   void PARAVIS_Gen_i::SaveTrace(const char* theFileName)
191   {
192     if(MYDEBUG) MESSAGE("PARAVIS_Gen_i::SaveTrace: " <<theFileName);
193     ProcessVoidEvent(new TSaveTrace(mySalomeApp, theFileName));
194   }
195
196   //----------------------------------------------------------------------------
197   void processElements(QDomNode& thePropertyNode, QStringList& theFileNames, const char* theNewPath, bool theRestore)
198   {
199     QDomNode aElementNode = thePropertyNode.firstChild();
200     while (aElementNode.isElement()) {
201       QDomElement aElement = aElementNode.toElement();
202       if (aElement.tagName() == "Element") {
203         QString aIndex = aElement.attribute("index");
204         if (aIndex == "0") {
205           QString aValue = aElement.attribute("value");
206           if (!aValue.isNull()) {
207             if (!theNewPath) {
208               QFileInfo aFInfo(aValue);
209               if (aFInfo.exists()) {
210                 theFileNames<<aValue;
211                 aElement.setAttribute("value", aFInfo.fileName());
212               }
213               break;
214             } else {
215               if (theRestore)
216                 aElement.setAttribute("value", QString(theNewPath) + aValue);
217             }
218           }
219         }
220       }
221       aElementNode = aElementNode.nextSibling();
222     }
223   }
224
225
226   //----------------------------------------------------------------------------
227   void processProperties(QDomNode& theProxyNode, QStringList& theFileNames, const char* theNewPath, bool theRestore)
228   {
229     QDomNode aPropertyNode = theProxyNode.firstChild();
230     while (aPropertyNode.isElement()) {
231       QDomElement aProperty = aPropertyNode.toElement();
232       QString aName = aProperty.attribute("name");
233       if ((aName == "FileName") || (aName == "FileNameInfo") || (aName == "FileNames")) {
234         processElements(aPropertyNode, theFileNames, theNewPath, theRestore);
235       }
236       aPropertyNode = aPropertyNode.nextSibling();
237     }
238   }  
239
240
241   //----------------------------------------------------------------------------
242   void processProxies(QDomNode& theNode, QStringList& theFileNames, const char* theNewPath, bool theRestore)
243   {
244     QDomNode aProxyNode = theNode.firstChild();
245     while (aProxyNode.isElement()) {
246       QDomElement aProxy = aProxyNode.toElement();
247       if (aProxy.tagName() == "Proxy") {
248         QString aGroup = aProxy.attribute("group");
249         if (aGroup == "sources") {
250           processProperties(aProxyNode, theFileNames, theNewPath, theRestore);
251         }
252       }
253       aProxyNode = aProxyNode.nextSibling();
254     }
255   }
256
257   //----------------------------------------------------------------------------
258   bool processAllFilesInState(const char* aFileName, QStringList& theFileNames,
259                               const char* theNewPath, bool theRestore = false)
260   {
261     QFile aFile(aFileName);
262     if (!aFile.open(QFile::ReadOnly)) {
263       MESSAGE("Can't open state file "<<aFileName);
264       return false;
265     }
266     QDomDocument aDoc;
267     bool aRes = aDoc.setContent(&aFile);
268     aFile.close();
269     
270     if (!aRes) {
271       MESSAGE("File "<<aFileName<<" is not XML document");
272       return false;
273     }
274     
275     QDomElement aRoot = aDoc.documentElement();
276     if ( aRoot.isNull() /*|| aRoot.tagName() != "SALOME" Names are different in various versions */ ) {
277       MESSAGE( "Invalid XML root" );
278       return false;
279     }
280
281     QDomNode aNode = aRoot.firstChild();
282     while (aRes  && !aNode.isNull() ) {
283       aRes = aNode.isElement();
284       if ( aRes ) {
285         QDomElement aSection = aNode.toElement();
286         if (aSection.tagName() == "ServerManagerState") {
287           processProxies(aNode, theFileNames, theNewPath, theRestore);
288         }
289       }
290       aNode = aNode.nextSibling();
291     }
292     if (!aFile.open(QFile::WriteOnly | QFile::Truncate)) {
293       MESSAGE("Can't open state file "<<aFileName<<" for writing");
294       return false;
295     }
296     QTextStream out(&aFile);
297     aDoc.save(out, 2);
298     aFile.close();
299     
300     return true;
301   }
302
303
304   SALOMEDS::TMPFile* SaveState(long thePID, SalomeApp_Application* theApp, SALOMEDS::SComponent_ptr theComponent, 
305                                const char* theURL, bool isMultiFile)
306   {
307     std::string aTmpDir = SALOMEDS_Tool::GetTmpDir();
308
309     std::ostringstream aStream;
310     aStream<<"paravisstate:"<<thePID;
311     std::string aFileName = "_" + aStream.str();
312     if(MYDEBUG) MESSAGE("aFileName = '"<<aFileName);
313
314     SALOMEDS::TMPFile_var aStreamFile = new SALOMEDS::TMPFile(0);
315
316     std::string aFile = aTmpDir + aFileName;
317     ProcessVoidEvent(new TSaveStateFile(theApp, aFile.c_str()));
318
319     // Collect all files from state
320     SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr();
321     int aSavingType = aResourceMgr->integerValue( "PARAVIS", "savestate_type", 0 );
322
323     QStringList aFileNames;
324     QStringList aNames;
325    
326     switch (aSavingType) {
327     case 0: // Save referenced files only for builin server
328       {
329         MESSAGE("Save as built in;")
330         bool aIsBuiltIn = true;
331         pqServer* aServer = ProcessEvent(new TGetActiveServer(theApp));
332         if (aServer) 
333           aIsBuiltIn != aServer->isRemote();
334       
335         if (aIsBuiltIn)
336         {
337           // Find referenced files and collect their paths nullyfying references
338           processAllFilesInState(aFile.c_str(), aFileNames, 0); 
339           SetRestoreParam(theComponent, true);
340         } else {
341           SetRestoreParam(theComponent, false);
342        }
343       }
344       break;
345     case 1: //Save referenced files when they are accessible
346       {
347         // Find referenced files and collect their paths nullyfying references
348         processAllFilesInState(aFile.c_str(), aFileNames, 0);
349         SetRestoreParam(theComponent, true);
350       }
351       break;
352     case 2: //Never save referenced files
353       SetRestoreParam(theComponent, false);
354       break;
355     }
356     aFileNames<<QString(aFile.c_str());
357     foreach(QString aFile, aFileNames) {
358       QFileInfo aInfo(aFile);
359       aNames<<aInfo.fileName();
360     }
361     SALOMEDS::ListOfFileNames_var aListOfFileNames = GetListOfFileNames(aFileNames);
362     SALOMEDS::ListOfFileNames_var aListOfNames = GetListOfFileNames(aNames);
363
364     aStreamFile = SALOMEDS_Tool::PutFilesToStream(aListOfFileNames.in(), aListOfNames.in());
365     //SALOMEDS_Tool::RemoveTemporaryFiles(theURL, aListOfFileNames, true);
366     
367     return aStreamFile._retn();
368   }
369
370   //----------------------------------------------------------------------------
371   SALOMEDS::TMPFile* PARAVIS_Gen_i::Save(SALOMEDS::SComponent_ptr theComponent, 
372                                          const char* theURL, bool isMultiFile)
373   {
374     if(MYDEBUG) MESSAGE("PARAVIS_Gen_i::Save - theURL = '"<<theURL<<"'");
375     return SaveState((long) this, mySalomeApp, theComponent, theURL, isMultiFile);
376   }
377     
378   //----------------------------------------------------------------------------
379   SALOMEDS::TMPFile* PARAVIS_Gen_i::SaveASCII(SALOMEDS::SComponent_ptr theComponent,
380                                               const char* theURL, bool isMultiFile)
381   {
382     if(MYDEBUG) MESSAGE("PARAVIS_Gen_i::Save - theURL = '"<<theURL<<"'");
383     return SaveState((long) this, mySalomeApp, theComponent, theURL, isMultiFile);
384   }
385     
386
387   //----------------------------------------------------------------------------
388   bool LoadState(SalomeApp_Application* theApp, SALOMEDS::SComponent_ptr theComponent,
389                  const SALOMEDS::TMPFile& theStream, const char* theURL, bool isMultiFile)
390   {
391     std::string aTmpDir = isMultiFile ? theURL : SALOMEDS_Tool::GetTmpDir();
392     if(MYDEBUG) MESSAGE("PARAVIS_Gen_i::Load - "<<aTmpDir);
393
394     SALOMEDS::ListOfFileNames_var aSeq = SALOMEDS_Tool::PutStreamToFiles(theStream, aTmpDir, false);
395     if (aSeq->length() == 0)
396       return false;
397
398     bool aRestore = GetRestoreParam(theComponent);
399     MESSAGE("PARAVIS_Gen_i::Restore path - "<<aRestore);
400
401     std::string aFile = aTmpDir + std::string(aSeq[aSeq->length() - 1]);
402     QStringList aEmptyList;
403     processAllFilesInState(aFile.c_str(), aEmptyList, aTmpDir.c_str(), aRestore);
404     ProcessVoidEvent(new TLoadStateFile(theApp, aFile.c_str()));
405
406     return true;
407   }
408
409   //----------------------------------------------------------------------------
410   bool PARAVIS_Gen_i::Load(SALOMEDS::SComponent_ptr theComponent,        const SALOMEDS::TMPFile& theStream,
411                            const char* theURL, bool isMultiFile)
412   {
413     return LoadState(mySalomeApp, theComponent, theStream, theURL, isMultiFile);
414   }
415
416   //----------------------------------------------------------------------------
417   bool PARAVIS_Gen_i::LoadASCII(SALOMEDS::SComponent_ptr theComponent, 
418                                 const SALOMEDS::TMPFile& theStream,
419                                 const char* theURL, bool isMultiFile)
420   {
421     return LoadState(mySalomeApp, theComponent, theStream, theURL, isMultiFile);
422   }
423     
424   //----------------------------------------------------------------------------
425   void PARAVIS_Gen_i::Close(SALOMEDS::SComponent_ptr IORSComponent)
426   {
427   }
428   
429   //----------------------------------------------------------------------------
430   char* PARAVIS_Gen_i::ComponentDataType()
431   {
432     return CORBA::string_dup("PARAVIS");
433   }
434
435   //----------------------------------------------------------------------------
436   char* PARAVIS_Gen_i::IORToLocalPersistentID(SALOMEDS::SObject_ptr theSObject, const char* IORString,
437                                               CORBA::Boolean isMultiFile, CORBA::Boolean isASCII)
438   {
439     CORBA::String_var aString("");
440     return aString._retn();
441   }
442
443   //----------------------------------------------------------------------------
444   char* PARAVIS_Gen_i::LocalPersistentIDToIOR(SALOMEDS::SObject_ptr theSObject, 
445                                               const char* aLocalPersistentID,
446                                               CORBA::Boolean isMultiFile, 
447                                               CORBA::Boolean isASCII)
448   {
449     CORBA::String_var aString("");
450     return aString._retn();
451   }
452
453   //----------------------------------------------------------------------------
454   bool PARAVIS_Gen_i::CanPublishInStudy(CORBA::Object_ptr theIOR)
455   {
456     return false;
457   }
458
459   //----------------------------------------------------------------------------
460   SALOMEDS::SObject_ptr PARAVIS_Gen_i::PublishInStudy(SALOMEDS::Study_ptr theStudy,
461                                                       SALOMEDS::SObject_ptr theSObject, 
462                                                       CORBA::Object_ptr theObject,
463                                                       const char* theName) 
464     throw (SALOME::SALOME_Exception)
465   {
466     SALOMEDS::SObject_var aResultSO;
467     return aResultSO._retn();
468   }
469
470   //----------------------------------------------------------------------------
471   CORBA::Boolean PARAVIS_Gen_i::CanCopy(SALOMEDS::SObject_ptr theObject)
472   {
473     return false;
474   }
475
476   //----------------------------------------------------------------------------
477   SALOMEDS::TMPFile* PARAVIS_Gen_i::CopyFrom(SALOMEDS::SObject_ptr theObject, CORBA::Long& theObjectID)
478   {
479     SALOMEDS::TMPFile_var aStreamFile = new SALOMEDS::TMPFile;
480     return aStreamFile._retn();
481   }
482
483   //----------------------------------------------------------------------------
484   CORBA::Boolean PARAVIS_Gen_i::CanPaste(const char* theComponentName, CORBA::Long theObjectID)
485   {
486     return false;
487   }
488
489   //----------------------------------------------------------------------------
490   SALOMEDS::SObject_ptr PARAVIS_Gen_i::PasteInto(const SALOMEDS::TMPFile& theStream,
491                                                  CORBA::Long theObjectID, SALOMEDS::SObject_ptr theObject)
492   {
493     return SALOMEDS::SObject::_nil();
494   }
495
496   //----------------------------------------------------------------------------
497   PARAVIS::string_array* PARAVIS_Gen_i::GetClassesList()
498   {
499     int k;
500     for (k = 0; strcmp(wrapped_classes[k], "") != 0; k++);
501     PARAVIS::string_array_var aNames = new PARAVIS::string_array();
502     aNames->length(k);
503     for (CORBA::ULong i = 0; i < k; i++)
504       aNames[i] = CORBA::string_dup(wrapped_classes[i]);
505     return aNames._retn();
506   }
507
508   //----------------------------------------------------------------------------
509   PARAVIS_Base_ptr PARAVIS_Gen_i::CreateClass(const char* theClassName)
510   {
511     PARAVIS::PARAVIS_Base_i* aClass = CreateInstance(NULL, QString(theClassName));
512     return aClass->_this();
513   }
514
515   //----------------------------------------------------------------------------
516   void PARAVIS_Gen_i::GetConnectionParameters(CORBA::Long& theId, 
517                                               CORBA::String_out theDHost, CORBA::Long& theDPort,
518                                               CORBA::String_out theRHost, CORBA::Long& theRPort,
519                                               CORBA::Long& theReversed)
520   {
521     pqServer* aServer = ProcessEvent(new TGetActiveServer(mySalomeApp));
522     if (aServer) {
523       theId = static_cast<int>(aServer->GetConnectionID());
524
525       pqServerResource serverRes = aServer->getResource();
526       theReversed = (serverRes.scheme() == "csrc" || serverRes.scheme() == "cdsrsrc")? 1 : 0;
527
528       theDPort = serverRes.dataServerPort() < 0? serverRes.port() : serverRes.dataServerPort();
529       theRPort = serverRes.renderServerPort() < 0 ? 0 : serverRes.renderServerPort();
530
531       QString dsHost = serverRes.dataServerHost().isEmpty()? serverRes.host() : serverRes.dataServerHost();
532       QString rsHost = serverRes.renderServerHost();
533
534       theDHost = CORBA::string_dup(qPrintable(dsHost));
535       theRHost = CORBA::string_dup(qPrintable(rsHost));
536     }
537   }
538
539
540   //----------------------------------------------------------------------------
541   Engines::TMPFile* PARAVIS_Gen_i::DumpPython(CORBA::Object_ptr theStudy,
542                                               CORBA::Boolean theIsPublished,
543                                               CORBA::Boolean& theIsValidScript)
544   {
545     theIsValidScript = true;
546     std::string aResult(ProcessEvent(new TGetTrace(mySalomeApp)));
547     aResult += "\ndef RebuildData(theStudy):\n  pass\n";
548     CORBA::ULong aSize = aResult.size() + 1;
549     char* aBuffer = new char[aSize];
550     memset(aBuffer, 0, aSize);
551     strcpy(aBuffer, &aResult[0]);
552     Engines::TMPFile_var aDump = new Engines::TMPFile(aSize,aSize,(CORBA::Octet*)aBuffer,1);
553     return aDump._retn();
554   }
555
556   //----------------------------------------------------------------------------
557   void PARAVIS_Gen_i::ActivateModule()
558   {
559     ProcessVoidEvent(new TActivateModule(mySalomeApp));
560   }
561 }