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