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