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