]> SALOME platform Git repositories - modules/gui.git/blob - src/SUIT/SUIT_Session.cxx
Salome HOME
baa32fd81576f8ef798c8fea51f7346e3cc8510d
[modules/gui.git] / src / SUIT / SUIT_Session.cxx
1 // Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
2 // 
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either 
6 // version 2.1 of the License.
7 // 
8 // This library is distributed in the hope that it will be useful 
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public  
14 // License along with this library; if not, write to the Free Software 
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/
18 //
19 #include "SUIT_Session.h"
20
21 #include "SUIT_Tools.h"
22 #include "SUIT_Desktop.h"
23 #include "SUIT_MessageBox.h"
24 #include "SUIT_ViewWindow.h"
25 #include "SUIT_ViewManager.h"
26 #include "SUIT_ExceptionHandler.h"
27
28 #include <qtextcodec.h>
29 #include <qmessagebox.h>
30 #include <qapplication.h>
31
32 #ifdef WIN32
33 #include <windows.h>
34 #else
35 #include <dlfcn.h>
36 #endif
37
38 SUIT_Session* SUIT_Session::mySession = 0;
39
40 /*! Constructor.*/
41
42 SUIT_Session::SUIT_Session()
43 : QObject(),
44 myResMgr( 0 ),
45 myHandler( 0 ),
46 myActiveApp( 0 ),
47 myExitStatus( FROM_GUI )
48 {
49   SUIT_ASSERT( !mySession )
50
51   mySession = this;
52
53   myAppList.setAutoDelete( true );
54 }
55
56 /*!destructor. Clear applications list and set mySession to zero.*/
57 SUIT_Session::~SUIT_Session()
58 {
59   myAppList.clear();
60
61   mySession = 0;
62 }
63
64 /*! \retval return mySession */
65 SUIT_Session* SUIT_Session::session()
66 {
67   return mySession;
68 }
69
70 /*!
71   Starts new application using "createApplication" function of loaded DLL.
72 */
73
74 SUIT_Application* SUIT_Session::startApplication( const QString& name, int args, char** argv )
75 {
76   AppLib libHandle = 0;
77
78   QString appName = applicationName( name );
79   if ( myAppLibs.contains( appName ) )
80     libHandle = myAppLibs[appName];
81
82   QString lib;
83   if ( !libHandle )
84     libHandle = loadLibrary( name, lib );
85
86   if ( !libHandle )
87   {
88     SUIT_MessageBox::warn1( 0, tr( "Error" ),
89                             tr( "Can not load application library \"%1\": %2").arg( lib ).arg( lastError() ), tr( "Ok" ) );
90     return 0;
91   }
92
93   if ( !myAppLibs.contains( appName ) || !myAppLibs[appName] ) // jfa 22.06.2005
94     myAppLibs.insert( appName, libHandle );
95
96   APP_CREATE_FUNC crtInst = 0;
97
98 #ifdef WIN32
99   crtInst = (APP_CREATE_FUNC)::GetProcAddress( libHandle, APP_CREATE_NAME );
100 #else
101   crtInst = (APP_CREATE_FUNC)dlsym( libHandle, APP_CREATE_NAME );
102 #endif
103
104   if ( !crtInst )
105   {
106     SUIT_MessageBox::warn1( 0, tr( "Error" ),
107                             tr( "Can not find function \"%1\": %2" ).arg( APP_CREATE_NAME ).arg( lastError() ), tr( "Ok" ) );
108     return 0;
109   }
110
111   // Prepare Resource Manager for the new application if it doesn't exist yet
112   if ( !myResMgr )
113   {
114     myResMgr = createResourceMgr( appName );
115     myResMgr->loadLanguage();
116   }
117
118   //jfa 22.06.2005:SUIT_Application* anApp = crtInst( args, argv );
119   SUIT_Application* anApp = crtInst();
120   if ( !anApp )
121   {
122     SUIT_MessageBox::warn1( 0, tr( "Error" ), tr( "Can not create application \"%1\": %2").arg( appName ).arg( lastError() ), tr( "Ok" ) );
123     return 0;
124   }
125
126   anApp->setName( appName );
127
128   connect( anApp, SIGNAL( applicationClosed( SUIT_Application* ) ),
129            this, SLOT( onApplicationClosed( SUIT_Application* ) ) );
130   connect( anApp, SIGNAL( activated( SUIT_Application* ) ), 
131                  this, SLOT( onApplicationActivated( SUIT_Application* ) ) );
132
133   myAppList.append( anApp );
134
135   if ( !myHandler )
136   {
137     APP_GET_HANDLER_FUNC crtHndlr = 0;
138 #ifdef WIN32
139     crtHndlr = (APP_GET_HANDLER_FUNC)::GetProcAddress( libHandle, APP_GET_HANDLER_NAME );
140 #else
141     crtHndlr = (APP_GET_HANDLER_FUNC)dlsym( libHandle, APP_GET_HANDLER_NAME );
142 #endif
143     if ( crtHndlr )
144       myHandler = crtHndlr();
145   }
146
147   anApp->start();
148
149   // Application can be closed during starting (not started).
150   if ( !myAppList.contains( anApp ) )
151     anApp = 0;
152
153   return anApp;
154 }
155
156 /*!
157   Gets the list of all applications
158 */
159 QPtrList<SUIT_Application> SUIT_Session::applications() const
160 {
161   QPtrList<SUIT_Application> apps;
162   apps.setAutoDelete( false );
163
164   for ( AppListIterator it( myAppList ); it.current(); ++it )
165     apps.append( it.current() );
166
167   return apps;
168 }
169
170 /*!
171   Returns the active application
172 */
173 SUIT_Application* SUIT_Session::activeApplication() const
174 {
175   /*
176   if ( myAppList.count() == 1 )
177     return myAppList.getFirst();
178
179   SUIT_Desktop* desktop = 0;
180   for ( AppListIterator it( myAppList ); it.current() && !desktop; ++it )
181   {
182     SUIT_Desktop* desk = it.current()->desktop();
183     if ( desk && desk->isActiveWindow() )
184       desktop = desk;
185   }
186
187   if ( !desktop )
188     return 0;
189
190   SUIT_ViewWindow* win = desktop->activeWindow();
191   if ( !win || !win->getViewManager() )
192     return 0;
193
194   SUIT_Study* study = win->getViewManager()->study();
195   if ( !study )
196     return 0;
197
198   return study->application();
199   */
200   return myActiveApp;
201 }
202
203 /*!
204   Returns the resource manager for the specified application name.
205 */
206 SUIT_ResourceMgr* SUIT_Session::resourceMgr() const
207 {
208   return myResMgr;
209 }
210
211 /*!
212   Removes the application from the list of launched applications.
213   If it is a last application the session will be closed.
214 */
215 void SUIT_Session::onApplicationClosed( SUIT_Application* theApp )
216 {
217   emit applicationClosed( theApp );
218
219   myAppList.remove( theApp );
220   if ( theApp == myActiveApp )
221     myActiveApp = 0;
222
223   if ( myAppList.isEmpty() )
224   {
225     printf( "Calling QApplication::exit() with exit code = %d\n", myExitStatus );
226     qApp->exit( myExitStatus );
227   }
228 }
229
230 /*!
231   Destroys session by closing all applications.
232 */
233 void SUIT_Session::closeSession( int mode )
234 {
235   while ( !myAppList.isEmpty() )
236   {
237     SUIT_Application* app = myAppList.getFirst();
238     if ( mode == ASK && !app->isPossibleToClose() )
239       return;
240     else if ( mode == SAVE )
241     {
242       SUIT_Study* study = app->activeStudy();
243       if ( study->isModified() && study->isSaved() )
244         study->saveDocument();
245     }
246     else if ( mode == DONT_SAVE )
247     {
248       myExitStatus = FROM_CORBA_SESSION;
249       //....
250     }
251
252     app->closeApplication();
253   }
254 }
255
256 /*! \retval return myHandler*/
257 SUIT_ExceptionHandler* SUIT_Session::handler() const
258 {
259   return myHandler;
260 }
261
262 /*! \retval return last error string.*/
263 QString SUIT_Session::lastError() const
264 {
265   QString str;
266 #ifdef WNT
267   LPVOID lpMsgBuf;
268   ::FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
269                    FORMAT_MESSAGE_IGNORE_INSERTS, 0, ::GetLastError(), 0, (LPTSTR)&lpMsgBuf, 0, 0 );
270   str = QString( (LPTSTR)lpMsgBuf );
271   LocalFree( lpMsgBuf );
272 #else
273   str = QString( dlerror() );
274 #endif
275   return str;
276 }
277
278 /*! Load library to session.
279  * \retval Loaded library.
280  */
281 SUIT_Session::AppLib SUIT_Session::loadLibrary( const QString& name, QString& libName )
282 {
283   QString libFile = SUIT_Tools::library( name );
284
285   libName = libFile;
286   if ( libFile.isEmpty() )
287     return 0;
288
289   AppLib lib = 0;
290 #ifdef WIN32
291   lib = ::LoadLibrary( (char*)libFile.latin1() );
292 #else
293   lib = dlopen( (char*)libFile.latin1(), RTLD_LAZY | RTLD_GLOBAL  );
294 #endif
295   return lib;
296 }
297
298 /*! \retval Return file name by application name.*/
299 QString SUIT_Session::applicationName( const QString& str ) const
300 {
301 #ifdef WIN32
302   return SUIT_Tools::file( str, false );
303 #else
304   QString fileName = SUIT_Tools::file( str, false );
305   if ( fileName.startsWith( "lib" ) )
306     fileName = fileName.right( fileName.length() - 3 );
307   return fileName;
308 #endif
309 }
310
311 /*!
312   Virtual method, creates an instance of ResourceManager
313 */
314 SUIT_ResourceMgr* SUIT_Session::createResourceMgr( const QString& appName ) const
315 {
316   return new SUIT_ResourceMgr( applicationName( appName ) );
317 }
318
319 /*!
320   Slot, called on activation of some application's desktop
321 */
322 void SUIT_Session::onApplicationActivated( SUIT_Application* app ) 
323 {
324   myActiveApp = app;
325 }