Salome HOME
SMH: Add again in binary mode
[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 SUIT_Session::SUIT_Session()
23 : QObject(),
24 myResMgr( 0 ),
25 myHandler( 0 )
26 {
27   SUIT_ASSERT( !mySession )
28
29   mySession = this;
30
31   myAppList.setAutoDelete( true );
32 }
33
34 SUIT_Session::~SUIT_Session()
35 {
36   myAppList.clear();
37
38   mySession = 0;
39 }
40
41 SUIT_Session* SUIT_Session::session()
42 {
43   return mySession;
44 }
45
46 /*!
47   Starts new application using "createApplication" function of loaded DLL.
48 */
49
50 SUIT_Application* SUIT_Session::startApplication( const QString& name, int args, char** argv )
51 {
52   AppLib libHandle = 0;
53
54   QString appName = applicationName( name );
55   if ( myAppLibs.contains( appName ) )
56     libHandle = myAppLibs[appName];
57
58   if ( !libHandle )
59     libHandle = loadLibrary( name );
60
61   if ( !libHandle )
62   {
63     SUIT_MessageBox::warn1( 0, tr( "Error" ),
64                             tr( "Can not find function %1. %2").arg( APP_CREATE_NAME ).arg( lastError() ), tr( "Ok" ) );
65     return 0;
66   }
67
68   myAppLibs.insert( appName, libHandle );
69
70   APP_CREATE_FUNC crtInst = 0;
71
72 #ifdef WIN32
73   crtInst = (APP_CREATE_FUNC)::GetProcAddress( libHandle, APP_CREATE_NAME );
74 #else
75   crtInst = (APP_CREATE_FUNC)dlsym( libHandle, APP_CREATE_NAME );
76 #endif
77
78   if ( !crtInst )
79   {
80     SUIT_MessageBox::warn1( 0, tr( "Error" ),
81                             tr( "Can not find function %1. %2").arg( APP_CREATE_NAME ).arg( lastError() ), tr( "Ok" ) );
82     return 0;
83   }
84
85   // Prepare Resource Manager for the new application if it doesn't exist yet
86   if ( !myResMgr )
87   {
88     myResMgr = createResourceMgr( appName );
89     myResMgr->loadLanguage();
90   }
91
92   SUIT_Application* anApp = crtInst( args, argv );
93   if ( !anApp )
94   {
95     SUIT_MessageBox::warn1(0, tr( "Error" ), tr( "Can not find function %1. %2").arg( APP_CREATE_NAME ).arg( lastError() ), tr( "Ok" ) );
96     return 0;
97   }
98
99   anApp->setName( appName );
100
101   connect( anApp, SIGNAL( applicationClosed( SUIT_Application* ) ),
102            this, SLOT( onApplicationClosed( SUIT_Application* ) ) );
103
104   myAppList.append( anApp );
105
106   if ( !myHandler )
107   {
108     APP_GET_HANDLER_FUNC crtHndlr = 0;
109 #ifdef WIN32
110     crtHndlr = (APP_GET_HANDLER_FUNC)::GetProcAddress( libHandle, APP_GET_HANDLER_NAME );
111 #else
112     crtHndlr = (APP_GET_HANDLER_FUNC)dlsym( libHandle, APP_GET_HANDLER_NAME );
113 #endif
114     if ( crtHndlr )
115       myHandler = crtHndlr();
116   }
117
118   anApp->start();
119
120   return anApp;
121 }
122
123 /*!
124   Gets the list of all applications
125 */
126 QPtrList<SUIT_Application> SUIT_Session::applications() const
127 {
128   QPtrList<SUIT_Application> apps;
129   apps.setAutoDelete( false );
130
131   for ( AppListIterator it( myAppList ); it.current(); ++it )
132     apps.append( it.current() );
133
134   return apps;
135 }
136
137 /*!
138   Returns the active application
139 */
140 SUIT_Application* SUIT_Session::activeApplication() const
141 {
142   if ( myAppList.count() == 1 )
143     return myAppList.getFirst();
144
145   SUIT_Desktop* desktop = 0;
146   for ( AppListIterator it( myAppList ); it.current() && !desktop; ++it )
147   {
148     SUIT_Desktop* desk = it.current()->desktop();
149     if ( desk && desk->isActiveWindow() )
150       desktop = desk;
151   }
152
153   if ( !desktop )
154     return 0;
155
156   SUIT_ViewWindow* win = desktop->activeWindow();
157   if ( !win || !win->getViewManager() )
158     return 0;
159
160   SUIT_Study* study = win->getViewManager()->study();
161   if ( !study )
162     return 0;
163
164   return study->application();
165 }
166
167 /*!
168   Returns the resource manager for the specified application name.
169 */
170 SUIT_ResourceMgr* SUIT_Session::resourceMgr() const
171 {
172   return myResMgr;
173 }
174
175 /*!
176   Removes the application from the list of launched applications.
177   If it is a last application the session will be closed.
178 */
179 void SUIT_Session::onApplicationClosed( SUIT_Application* theApp )
180 {
181   emit applicationClosed( theApp );
182
183   myAppList.remove( theApp );
184
185   if ( myAppList.isEmpty() )
186     qApp->quit();
187 }
188
189 /*!
190   Destroys session by closing all applications.
191 */
192 void SUIT_Session::closeSession()
193 {
194   while ( !myAppList.isEmpty() )
195   {
196     SUIT_Application* app = myAppList.getFirst();
197     if ( !app->isPossibleToClose() )
198       return;
199
200     app->closeApplication();
201   }
202 }
203
204 SUIT_ExceptionHandler* SUIT_Session::handler() const
205 {
206   return myHandler;
207 }
208
209 QString SUIT_Session::lastError() const
210 {
211   QString str;
212 #ifdef WNT
213   LPVOID lpMsgBuf;
214   ::FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
215                    FORMAT_MESSAGE_IGNORE_INSERTS, 0, ::GetLastError(), 0, (LPTSTR)&lpMsgBuf, 0, 0 );
216   str = QString( (LPTSTR)lpMsgBuf );
217   LocalFree( lpMsgBuf );
218 #else
219   str = QString( dlerror() );
220 #endif
221   return str;
222 }
223
224 SUIT_Session::AppLib SUIT_Session::loadLibrary( const QString& name )
225 {
226   QString libFile = SUIT_Tools::library( name );
227
228   if ( libFile.isEmpty() )
229     return 0;
230
231   AppLib lib = 0;
232 #ifdef WIN32
233   lib = ::LoadLibrary( (char*)libFile.latin1() );
234 #else
235   lib = dlopen( (char*)libFile.latin1(), RTLD_LAZY );
236 #endif
237   return lib;
238 }
239
240 QString SUIT_Session::applicationName( const QString& str ) const
241 {
242 #ifdef WIN32
243   return SUIT_Tools::file( str, false );
244 #else
245   QString fileName = SUIT_Tools::file( str, false );
246   if ( fileName.startsWith( "lib" ) )
247     fileName = fileName.right( fileName.length() - 3 );
248   return fileName;
249 #endif
250 }
251
252 /*!
253   Virtual method, creates an instance of ResourceManager
254 */
255 SUIT_ResourceMgr* SUIT_Session::createResourceMgr( const QString& appName ) const
256 {
257   return new SUIT_ResourceMgr( appName );
258 }