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