Salome HOME
Merge branch 'V7_dev'
[modules/gui.git] / src / Session / Session_Session_i.cxx
1 // Copyright (C) 2007-2016  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, or (at your option) any later version.
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 //  File   : SALOME_Session_i.cxx
23 //  Author : Paul RASCLE, EDF
24 //  Module : SALOME
25
26 #include "utilities.h"
27
28 #include "Session_Session_i.hxx"
29
30 #include "SALOME_NamingService.hxx"
31 #include "SALOME_Event.h"
32 #include "SalomeApp_Engine_i.h"
33 #include "LightApp_Application.h"
34 #include "LightApp_SelectionMgr.h"
35 #include "SALOME_ListIO.hxx"
36 #include "SUIT_Session.h"
37 #include "SUIT_Desktop.h"
38 #include "SUIT_Study.h"
39
40 #include "Basics_Utils.hxx"
41
42 #include <QMutex>
43 #include <QWaitCondition>
44
45 // Open CASCADE Includes
46 #include <OSD_SharedLibrary.hxx>
47 #include <OSD_Function.hxx>
48
49 #ifdef WIN32
50 # include <process.h>
51 #else
52 #include <unistd.h>
53 #endif
54
55 /*!
56   constructor
57 */
58 SALOME_Session_i::SALOME_Session_i(int argc,
59                                    char ** argv,
60                                    CORBA::ORB_ptr orb,
61                                    PortableServer::POA_ptr poa,
62                                    QMutex* GUIMutex,
63                                    QWaitCondition* GUILauncher)
64 {
65   _argc = argc ;
66   _argv = argv ;
67   _isGUI = false ;
68   _runningStudies= 0 ;
69   _orb = CORBA::ORB::_duplicate(orb) ;
70   _poa = PortableServer::POA::_duplicate(poa) ;
71   _GUIMutex = GUIMutex;
72   _GUILauncher = GUILauncher;
73   _NS = new SALOME_NamingService(_orb);
74   _isShuttingDown = false;
75   //MESSAGE("constructor end");
76 }
77
78 /*!
79   returns Visu component
80 */
81 Engines::EngineComponent_ptr SALOME_Session_i::GetComponent(const char* theLibraryName)
82 {
83   typedef Engines::EngineComponent_ptr TGetImpl(CORBA::ORB_ptr,
84                                                 PortableServer::POA_ptr,
85                                                 SALOME_NamingService*,QMutex*);
86   OSD_SharedLibrary aSharedLibrary(const_cast<char*>(theLibraryName));
87   if (aSharedLibrary.DlOpen(OSD_RTLD_LAZY)) {
88     if (OSD_Function anOSDFun = aSharedLibrary.DlSymb("GetImpl"))
89       return ((TGetImpl (*)) anOSDFun)(_orb,_poa,_NS,_GUIMutex);
90   }
91   CORBA::Object_var obj = SalomeApp_Engine_i::EngineForComponent(theLibraryName, true);
92   if (!CORBA::is_nil(obj)){
93     Engines::EngineComponent_var anEngine = Engines::EngineComponent::_narrow(obj);
94     return anEngine._retn();
95   }
96   return Engines::EngineComponent::_nil();
97 }
98
99 /*!
100   destructor
101 */
102 SALOME_Session_i::~SALOME_Session_i()
103 {
104   delete _NS;
105   //MESSAGE("destructor end");
106 }
107
108 /*!
109   tries to find the Corba Naming Service and to register the session,
110   gives naming service interface to _IAPPThread
111 */
112 void SALOME_Session_i::NSregister()
113 {
114   CORBA::Object_var obref=_this();
115   SALOME::Session_var pSession = SALOME::Session::_narrow(obref);
116   try
117     {
118       _NS->Register(pSession, "/Kernel/Session");
119     }
120   catch (ServiceUnreachable&)
121     {
122       INFOS("Caught exception: Naming Service Unreachable");
123       exit(1) ;
124     }
125   catch (...)
126     {
127       INFOS("Caught unknown exception from Naming Service");
128     }
129   //MESSAGE("Session registered in Naming Service");
130 }
131
132 /*!
133   Unregister session server from CORBA Naming Service
134 */
135 void SALOME_Session_i::NSunregister()
136 {
137   try
138     {
139       _NS->Destroy_Name("/Kernel/Session");
140     }
141   catch (ServiceUnreachable&)
142     {
143       INFOS("Caught exception: Naming Service Unreachable");
144     }
145   catch (...)
146     {
147       INFOS("Caught unknown exception from Naming Service");
148     }
149 }
150
151 /*!
152   Launches the GUI if there is none.
153   The Corba method is oneway (corba client does'nt wait for GUI completion)
154 */
155 void SALOME_Session_i::GetInterface()
156 {
157   _GUIMutex->lock();
158   _GUIMutex->unlock();
159   if ( !SUIT_Session::session() )
160   {
161     _GUILauncher->wakeAll();
162     MESSAGE("SALOME_Session_i::GetInterface() called, starting GUI...");
163   }
164 }
165
166 /*!
167   Kills the session if there are no active studies nore GUI
168 */
169 class CloseEvent : public SALOME_Event
170 {
171 public:
172   virtual void Execute() {
173     if ( SUIT_Session::session() )
174       SUIT_Session::session()->closeSession( SUIT_Session::DONT_SAVE );
175   }
176 };
177
178 /*!
179   Stop session (close all GUI windows)
180 */
181 void SALOME_Session_i::StopSession()
182 {
183   _GUIMutex->lock();
184   _GUIMutex->unlock();
185   if ( SUIT_Session::session() ) {
186     ProcessVoidEvent( new CloseEvent() );
187   }
188 }
189
190 //! Shutdown session
191 void SALOME_Session_i::Shutdown()
192 {
193   _GUIMutex->lock();
194   bool isBeingShuttingDown = _isShuttingDown;
195   _isShuttingDown = true;
196   _GUIMutex->unlock();
197   if ( !isBeingShuttingDown ) {
198     if ( SUIT_Session::session() ) {
199       ProcessVoidEvent( new CloseEvent() );
200     }
201     else {
202       _GUILauncher->wakeAll();
203     }
204   }
205 }
206
207 /*!
208   Send a SALOME::StatSession structure (see idl) to the client
209   (number of running studies and presence of GUI)
210 */
211 /*class QtLock
212 {
213 public:
214   QtLock() { if ( qApp ) qApp->lock(); }
215   ~QtLock() { if ( qApp ) qApp->unlock(); }
216 };*/
217
218
219 SALOME::StatSession SALOME_Session_i::GetStatSession()
220 {
221   // update Session state
222   _GUIMutex->lock();
223
224   _runningStudies = 0;
225   {
226     //QtLock lock;
227     _isGUI = SUIT_Session::session();
228     if ( _isGUI && SUIT_Session::session()->activeApplication() )
229       _runningStudies = SUIT_Session::session()->activeApplication()->getNbStudies();
230   }
231
232   // getting stat info
233   SALOME::StatSession_var myStats = new SALOME::StatSession ;
234   if (_runningStudies)
235     myStats->state = SALOME::running ;
236   else if (_isShuttingDown)
237     myStats->state = SALOME::shutdown ;
238   else
239     myStats->state = SALOME::asleep ;
240   myStats->runningStudies = _runningStudies ;
241   myStats->activeGUI = _isGUI ;
242
243   _GUIMutex->unlock();
244
245   return myStats._retn() ;
246 }
247
248 CORBA::Long SALOME_Session_i::GetActiveStudyId()
249 {
250   long aStudyId=-1;
251   if ( SUIT_Session::session() && SUIT_Session::session()->activeApplication() ) {
252     if ( SUIT_Session::session()->activeApplication()->activeStudy() ) // mkr : IPAL12128
253       aStudyId = SUIT_Session::session()->activeApplication()->activeStudy()->id();
254   }
255   return aStudyId;
256 }
257
258 CORBA::Long SALOME_Session_i::getPID() {
259   return (CORBA::Long)
260 #ifndef WIN32
261     getpid();
262 #else
263     _getpid();
264 #endif
265 }
266
267 char* SALOME_Session_i::getHostname()
268 {
269   std::string aHostName = Kernel_Utils::GetHostname();
270   return CORBA::string_dup( aHostName.data() );
271 }
272
273 bool SALOME_Session_i::restoreVisualState(CORBA::Long theSavePoint)
274 {
275   class TEvent: public SALOME_Event {
276     int _savePoint;
277   public:
278     TEvent(int savePoint) { _savePoint = savePoint; }
279     virtual void Execute() {
280       SUIT_Study* study = SUIT_Session::session()->activeApplication()->activeStudy();
281       if ( study ) {
282         study->restoreState(_savePoint);
283       }
284     }
285   };
286   
287   if(SUIT_Session::session() && SUIT_Session::session()->activeApplication() ) {
288     SUIT_Study* study = SUIT_Session::session()->activeApplication()->activeStudy();
289     if(!study) SUIT_Session::session()->activeApplication()->createEmptyStudy();      
290     ProcessVoidEvent( new TEvent(theSavePoint) );
291     return true;
292   }
293  
294   return false;
295 }
296
297 void SALOME_Session_i::emitMessage(const char* theMessage)
298 {
299   class TEvent: public SALOME_Event {
300   public:
301     TEvent(const char * msg) {
302       _msg = msg;
303     }
304     virtual void Execute() {
305       SUIT_Session::session()->activeApplication()->desktop()->emitMessage(_msg);
306     }
307   private:
308     const char* _msg;
309   };
310   if ( SUIT_Session::session() ) {
311     if ( SUIT_Session::session()->activeApplication() ) {
312       if ( SUIT_Session::session()->activeApplication()->desktop() ) {
313         ProcessVoidEvent( new TEvent(theMessage) );
314       }
315       else {
316         MESSAGE("try to emit message '"<<theMessage<<"' but there is no desktop");
317       }
318     }
319     else {
320       MESSAGE("try to emit message '"<<theMessage<<"' but there is no application");
321     }
322   }
323   else {
324     MESSAGE("try to emit message '"<<theMessage<<"' but there is no session");
325   }
326 }
327
328 void SALOME_Session_i::emitMessageOneWay(const char* theMessage)
329 {
330   emitMessage(theMessage);
331 }
332
333 SALOME::StringSeq* SALOME_Session_i::getSelection()
334 {
335   SALOME::StringSeq_var selection = new SALOME::StringSeq;
336   _GUIMutex->lock();
337   if ( SUIT_Session::session() ) {
338     LightApp_Application* app = dynamic_cast<LightApp_Application*>( SUIT_Session::session()->activeApplication() );
339     if ( app ) {
340       LightApp_SelectionMgr* selMgr = dynamic_cast<LightApp_SelectionMgr*>( app->selectionMgr() );
341       SALOME_ListIO selected;
342       selMgr->selectedObjects( selected );
343       selection->length( selected.Extent() );
344       int nbSel = 0;
345       for ( SALOME_ListIteratorOfListIO it( selected ); it.More(); it.Next() ) {
346         Handle( SALOME_InteractiveObject ) io = it.Value();
347         if ( io->hasEntry() )
348           selection[nbSel++] = CORBA::string_dup( io->getEntry() );
349       }
350       selection->length( nbSel );
351     }
352   }
353   _GUIMutex->unlock();
354   return selection._retn();
355 }