Salome HOME
updated copyright message
[modules/gui.git] / src / Session / Session_Session_i.cxx
old mode 100755 (executable)
new mode 100644 (file)
index ee23967..ffa472d
@@ -1,84 +1,91 @@
-//  SALOME Session : implementation of Session.idl
+// Copyright (C) 2007-2023  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
 //
-//  This library is free software; you can redistribute it and/or
-//  modify it under the terms of the GNU Lesser General Public
-//  License as published by the Free Software Foundation; either
-//  version 2.1 of the License.
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
 //
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
 //
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
-//
-//
 //  File   : SALOME_Session_i.cxx
 //  Author : Paul RASCLE, EDF
 //  Module : SALOME
-//  $Header$
 
 #include "utilities.h"
 
 #include "Session_Session_i.hxx"
 
 #include "SALOME_NamingService.hxx"
-#include "SALOME_Event.hxx"
-
+#include "SALOME_Event.h"
+#include "SalomeApp_Engine_i.h"
+#include "LightApp_Application.h"
+#include "LightApp_SelectionMgr.h"
+#include "SALOME_ListIO.hxx"
 #include "SUIT_Session.h"
-#include "SUIT_Application.h"
+#include "SUIT_Desktop.h"
+#include "SUIT_Study.h"
 
-#include <qapplication.h>
+#include "Basics_Utils.hxx"
+
+#include <QMutex>
+#include <QWaitCondition>
 
 // Open CASCADE Includes
 #include <OSD_SharedLibrary.hxx>
-#include <OSD_LoadMode.hxx>
 #include <OSD_Function.hxx>
 
-using namespace std;
+#ifdef WIN32
+# include <process.h>
+#else
+#include <unistd.h>
+#endif
 
-/*!
-  constructor
-*/
-SALOME_Session_i::SALOME_Session_i(int argc,
-                                  char ** argv,
-                                  CORBA::ORB_ptr orb,
-                                  PortableServer::POA_ptr poa,
-                                  QMutex* GUIMutex,
-                                  QWaitCondition* GUILauncher)
-{
-  _argc = argc ;
-  _argv = argv ;
-  _isGUI = FALSE ;
-  _runningStudies= 0 ;
-  _orb = CORBA::ORB::_duplicate(orb) ;
-  _poa = PortableServer::POA::_duplicate(poa) ;
-  _GUIMutex = GUIMutex;
-  _GUILauncher = GUILauncher;
-  //MESSAGE("constructor end");
+SALOME_Session_i::SALOME_Session_i(int argc, char ** argv, CORBA::ORB_ptr orb, PortableServer::POA_ptr poa, QMutex* GUIMutex, QWaitCondition* GUILauncher):
+_argc(argc),_argv(argv),_isGUI(false),_GUIMutex(GUIMutex),_GUILauncher(GUILauncher),
+_orb(CORBA::ORB::_duplicate(orb)),_poa(PortableServer::POA::_duplicate(poa)),_isShuttingDown(false)
+{
+  _NS.reset(new SALOME_NamingService(_orb));
+}
+
+SALOME_Session_i::SALOME_Session_i(int argc, char ** argv, CORBA::ORB_ptr orb, PortableServer::POA_ptr poa, QMutex* GUIMutex, QWaitCondition* GUILauncher, SALOME_NamingService_Abstract *NS):
+_argc(argc),_argv(argv),_isGUI(false),_GUIMutex(GUIMutex),_GUILauncher(GUILauncher),
+_orb(CORBA::ORB::_duplicate(orb)),_poa(PortableServer::POA::_duplicate(poa)),_isShuttingDown(false)
+{
+  _NS.reset(NS);
 }
 
 /*!
   returns Visu component
 */
-Engines::Component_ptr SALOME_Session_i::GetComponent(const char* theLibraryName)
+Engines::EngineComponent_ptr SALOME_Session_i::GetComponent(const char* theLibraryName)
 {
-  typedef Engines::Component_ptr TGetImpl(CORBA::ORB_ptr,
-                                         PortableServer::POA_ptr,
-                                         SALOME_NamingService*,QMutex*);
-  OSD_SharedLibrary  aSharedLibrary(const_cast<char*>(theLibraryName));
-  if(aSharedLibrary.DlOpen(OSD_RTLD_LAZY))
-    if(OSD_Function anOSDFun = aSharedLibrary.DlSymb("GetImpl"))
-      return ((TGetImpl (*)) anOSDFun)(_orb,_poa,_NS,_GUIMutex);
-  return Engines::Component::_nil();
+  using TGetImpl = Engines::EngineComponent_ptr (*)(CORBA::ORB_ptr, PortableServer::POA_ptr, SALOME_NamingService*,QMutex*);
+  OSD_SharedLibrary aSharedLibrary(const_cast<char*>(theLibraryName));
+  if (aSharedLibrary.DlOpen(OSD_RTLD_LAZY)) {
+    if (OSD_Function anOSDFun = aSharedLibrary.DlSymb("GetImpl"))
+    {
+      Engines::EngineComponent_ptr ret = ((TGetImpl) anOSDFun)(_orb,_poa,dynamic_cast<SALOME_NamingService*>(_NS.get()),_GUIMutex);
+      return ret;
+    }
+  }
+  CORBA::Object_var obj = SalomeApp_Engine_i::EngineForComponent(theLibraryName, true);
+  if (!CORBA::is_nil(obj)){
+    Engines::EngineComponent_var anEngine = Engines::EngineComponent::_narrow(obj);
+    return anEngine._retn();
+  }
+  return Engines::EngineComponent::_nil();
 }
 
 /*!
@@ -95,10 +102,10 @@ SALOME_Session_i::~SALOME_Session_i()
 */
 void SALOME_Session_i::NSregister()
 {
-  SALOME::Session_ptr pSession = SALOME::Session::_narrow(_this());
+  CORBA::Object_var obref=_this();
+  SALOME::Session_var pSession = SALOME::Session::_narrow(obref);
   try
     {
-      _NS = new SALOME_NamingService(_orb);
       _NS->Register(pSession, "/Kernel/Session");
     }
   catch (ServiceUnreachable&)
@@ -113,6 +120,27 @@ void SALOME_Session_i::NSregister()
   //MESSAGE("Session registered in Naming Service");
 }
 
+/*!
+  Unregister session server from CORBA Naming Service
+*/
+void SALOME_Session_i::NSunregister()
+{
+  try
+    {
+      _NS->Destroy_Name("/Kernel/Session");
+      _NS->Destroy_Directory("/Kernel");
+      deleteContainersinNS();
+    }
+  catch (ServiceUnreachable&)
+    {
+      INFOS("Caught exception: Naming Service Unreachable");
+    }
+  catch (...)
+    {
+      INFOS("Caught unknown exception from Naming Service");
+    }
+}
+
 /*!
   Launches the GUI if there is none.
   The Corba method is oneway (corba client does'nt wait for GUI completion)
@@ -124,8 +152,8 @@ void SALOME_Session_i::GetInterface()
   if ( !SUIT_Session::session() )
   {
     _GUILauncher->wakeAll();
-    MESSAGE("SALOME_Session_i::GetInterface() called, starting GUI...")
-      }
+    MESSAGE("SALOME_Session_i::GetInterface() called, starting GUI...");
+  }
 }
 
 /*!
@@ -135,67 +163,93 @@ class CloseEvent : public SALOME_Event
 {
 public:
   virtual void Execute() {
-    SUIT_Session* session = SUIT_Session::session();
-    session->closeSession( SUIT_Session::DONT_SAVE );
-    //if ( SUIT_Application::getDesktop() )
-    //  QAD_Application::getDesktop()->closeDesktop( true );
+    if ( SUIT_Session::session() )
+      SUIT_Session::session()->closeSession( SUIT_Session::DONT_SAVE );
   }
 };
 
 /*!
-  Processes event to close session
+  Stop session (close all GUI windows)
 */
 void SALOME_Session_i::StopSession()
 {
-  ProcessVoidEvent( new CloseEvent() );
+  _GUIMutex->lock();
+  _GUIMutex->unlock();
+  if ( SUIT_Session::session() ) {
+    ProcessVoidEvent( new CloseEvent() );
+  }
+}
+
+//! Shutdown session
+void SALOME_Session_i::Shutdown()
+{
+  _GUIMutex->lock();
+  bool isBeingShuttingDown = _isShuttingDown;
+  _isShuttingDown = true;
+  _GUIMutex->unlock();
+  if ( !isBeingShuttingDown ) {
+    if ( SUIT_Session::session() ) {
+      ProcessVoidEvent( new CloseEvent() );
+    }
+    else {
+      _GUILauncher->wakeAll();
+    }
+  }
 }
 
 /*!
   Send a SALOME::StatSession structure (see idl) to the client
-  (number of running studies and presence of GUI)
+  (presence of GUI)
 */
-class QtLock
+/*class QtLock
 {
 public:
   QtLock() { if ( qApp ) qApp->lock(); }
   ~QtLock() { if ( qApp ) qApp->unlock(); }
-};
+};*/
 
 
 SALOME::StatSession SALOME_Session_i::GetStatSession()
 {
   // update Session state
   _GUIMutex->lock();
+  int activeStudy = 0;
 
-  _runningStudies = 0;
   {
-    QtLock lock;
+    //QtLock lock;
     _isGUI = SUIT_Session::session();
     if ( _isGUI && SUIT_Session::session()->activeApplication() )
-      _runningStudies = SUIT_Session::session()->activeApplication()->getNbStudies();
+      activeStudy = SUIT_Session::session()->activeApplication()->getNbStudies();
   }
 
-  _GUIMutex->unlock();
-
   // getting stat info
-  SALOME::StatSession_var myStats = new SALOME::StatSession ;
-  if (_runningStudies)
+  SALOME::StatSession_var myStats = new SALOME::StatSession;
+  if (activeStudy)
     myStats->state = SALOME::running ;
+  else if (_isShuttingDown)
+    myStats->state = SALOME::shutdown ;
   else
     myStats->state = SALOME::asleep ;
-  myStats->runningStudies = _runningStudies ;
   myStats->activeGUI = _isGUI ;
+
+  _GUIMutex->unlock();
+
   return myStats._retn() ;
 }
 
-CORBA::Long SALOME_Session_i::GetActiveStudyId()
+CORBA::Long SALOME_Session_i::getPID() {
+  return (CORBA::Long)
+#ifndef WIN32
+    getpid();
+#else
+    _getpid();
+#endif
+}
+
+char* SALOME_Session_i::getHostname()
 {
-  long aStudyId=-1;
-  if ( SUIT_Session::session() && SUIT_Session::session()->activeApplication() ) {
-    if ( SUIT_Session::session()->activeApplication()->activeStudy() ) // mkr : IPAL12128
-      aStudyId = SUIT_Session::session()->activeApplication()->activeStudy()->id();
-  }
-  return aStudyId;
+  std::string aHostName = Kernel_Utils::GetHostname();
+  return CORBA::string_dup( aHostName.data() );
 }
 
 bool SALOME_Session_i::restoreVisualState(CORBA::Long theSavePoint)
@@ -207,7 +261,7 @@ bool SALOME_Session_i::restoreVisualState(CORBA::Long theSavePoint)
     virtual void Execute() {
       SUIT_Study* study = SUIT_Session::session()->activeApplication()->activeStudy();
       if ( study ) {
-       study->restoreState(_savePoint);
+        study->restoreState(_savePoint);
       }
     }
   };
@@ -221,3 +275,90 @@ bool SALOME_Session_i::restoreVisualState(CORBA::Long theSavePoint)
  
   return false;
 }
+
+void SALOME_Session_i::emitMessage(const char* theMessage)
+{
+  class TEvent: public SALOME_Event {
+  public:
+    TEvent(const char * msg) {
+      _msg = msg;
+    }
+    virtual void Execute() {
+      SUIT_Session::session()->activeApplication()->desktop()->emitMessage(_msg);
+    }
+  private:
+    const char* _msg;
+  };
+  if ( SUIT_Session::session() ) {
+    if ( SUIT_Session::session()->activeApplication() ) {
+      if ( SUIT_Session::session()->activeApplication()->desktop() ) {
+        ProcessVoidEvent( new TEvent(theMessage) );
+      }
+      else {
+       MESSAGE("try to emit message '"<<theMessage<<"' but there is no desktop");
+      }
+    }
+    else {
+      MESSAGE("try to emit message '"<<theMessage<<"' but there is no application");
+    }
+  }
+  else {
+    MESSAGE("try to emit message '"<<theMessage<<"' but there is no session");
+  }
+}
+
+void SALOME_Session_i::emitMessageOneWay(const char* theMessage)
+{
+  emitMessage(theMessage);
+}
+
+SALOME::StringSeq* SALOME_Session_i::getSelection()
+{
+  SALOME::StringSeq_var selection = new SALOME::StringSeq;
+  _GUIMutex->lock();
+  if ( SUIT_Session::session() ) {
+    LightApp_Application* app = dynamic_cast<LightApp_Application*>( SUIT_Session::session()->activeApplication() );
+    if ( app ) {
+      LightApp_SelectionMgr* selMgr = dynamic_cast<LightApp_SelectionMgr*>( app->selectionMgr() );
+      SALOME_ListIO selected;
+      selMgr->selectedObjects( selected );
+      selection->length( selected.Extent() );
+      int nbSel = 0;
+      for ( SALOME_ListIteratorOfListIO it( selected ); it.More(); it.Next() ) {
+        Handle( SALOME_InteractiveObject ) io = it.Value();
+        if ( io->hasEntry() )
+          selection[nbSel++] = CORBA::string_dup( io->getEntry() );
+      }
+      selection->length( nbSel );
+    }
+  }
+  _GUIMutex->unlock();
+  return selection._retn();
+}
+
+void SALOME_Session_i::deleteContainersinNS()
+{
+// destroy of all containers and modules
+  _NS->Change_Directory("/Containers");
+  std::vector<std::string> machines = _NS->list_subdirs();
+  for(int i=0;i<(int)machines.size();i++){
+    _NS->Change_Directory(machines[i].c_str());
+    std::vector<std::string> toto = _NS->list_directory();
+    for(int j=0;j<(int)toto.size();j++)
+      _NS->Destroy_Name(toto[j].c_str());
+    std::vector<std::string> containers = _NS->list_subdirs();
+    for(int j=0;j<(int)containers.size();j++){
+      _NS->Change_Directory(containers[j].c_str());
+      std::vector<std::string> modules = _NS->list_directory();
+      for(int k=0;k<(int)modules.size();k++)
+        _NS->Destroy_Name(modules[k].c_str());
+      _NS->Change_Directory("/Containers");
+      _NS->Change_Directory(machines[i].c_str());
+      _NS->Destroy_Directory(containers[j].c_str());
+    }
+    _NS->Change_Directory("/Containers");
+    _NS->Destroy_Directory(machines[i].c_str());
+  }
+  _NS->Change_Directory("/");
+  _NS->Destroy_Directory("/Containers");
+}