1 // Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 #include "SUIT_Session.h"
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"
28 #include <qtextcodec.h>
29 #include <qmessagebox.h>
30 #include <qapplication.h>
38 static bool SUIT_Session_IsPythonExecuted = false;
39 static QMutex SUIT_Session_PythonMutex;
41 SUIT_Session* SUIT_Session::mySession = 0;
45 SUIT_Session::SUIT_Session()
50 myExitStatus( NORMAL ),
53 SUIT_ASSERT( !mySession )
57 myAppList.setAutoDelete( true );
60 /*!destructor. Clear applications list and set mySession to zero.*/
61 SUIT_Session::~SUIT_Session()
72 /*! \retval return mySession */
73 SUIT_Session* SUIT_Session::session()
79 Starts new application using "createApplication" function of loaded DLL.
82 SUIT_Application* SUIT_Session::startApplication( const QString& name, int args, char** argv )
86 QString appName = applicationName( name );
87 if ( myAppLibs.contains( appName ) )
88 libHandle = myAppLibs[appName];
92 libHandle = loadLibrary( name, lib );
96 SUIT_MessageBox::warn1( 0, tr( "Error" ),
97 tr( "Can not load application library \"%1\": %2").arg( lib ).arg( lastError() ), tr( "Ok" ) );
101 if ( !myAppLibs.contains( appName ) || !myAppLibs[appName] ) // jfa 22.06.2005
102 myAppLibs.insert( appName, libHandle );
104 APP_CREATE_FUNC crtInst = 0;
107 crtInst = (APP_CREATE_FUNC)::GetProcAddress( libHandle, APP_CREATE_NAME );
109 crtInst = (APP_CREATE_FUNC)dlsym( libHandle, APP_CREATE_NAME );
114 SUIT_MessageBox::warn1( 0, tr( "Error" ),
115 tr( "Can not find function \"%1\": %2" ).arg( APP_CREATE_NAME ).arg( lastError() ), tr( "Ok" ) );
119 // Prepare Resource Manager for the new application if it doesn't exist yet
122 myResMgr = createResourceMgr( appName );
123 myResMgr->loadLanguage();
126 //jfa 22.06.2005:SUIT_Application* anApp = crtInst( args, argv );
127 SUIT_Application* anApp = crtInst();
130 SUIT_MessageBox::warn1( 0, tr( "Error" ), tr( "Can not create application \"%1\": %2").arg( appName ).arg( lastError() ), tr( "Ok" ) );
134 anApp->setName( appName );
136 connect( anApp, SIGNAL( applicationClosed( SUIT_Application* ) ),
137 this, SLOT( onApplicationClosed( SUIT_Application* ) ) );
138 connect( anApp, SIGNAL( activated( SUIT_Application* ) ),
139 this, SLOT( onApplicationActivated( SUIT_Application* ) ) );
141 myAppList.append( anApp );
145 APP_GET_HANDLER_FUNC crtHndlr = 0;
147 crtHndlr = (APP_GET_HANDLER_FUNC)::GetProcAddress( libHandle, APP_GET_HANDLER_NAME );
149 crtHndlr = (APP_GET_HANDLER_FUNC)dlsym( libHandle, APP_GET_HANDLER_NAME );
152 myHandler = crtHndlr();
157 // Application can be closed during starting (not started).
158 if ( !myAppList.contains( anApp ) )
165 Gets the list of all applications
167 QPtrList<SUIT_Application> SUIT_Session::applications() const
169 QPtrList<SUIT_Application> apps;
170 apps.setAutoDelete( false );
172 for ( AppListIterator it( myAppList ); it.current(); ++it )
173 apps.append( it.current() );
179 Returns the active application
181 SUIT_Application* SUIT_Session::activeApplication() const
184 if ( myAppList.count() == 1 )
185 return myAppList.getFirst();
187 SUIT_Desktop* desktop = 0;
188 for ( AppListIterator it( myAppList ); it.current() && !desktop; ++it )
190 SUIT_Desktop* desk = it.current()->desktop();
191 if ( desk && desk->isActiveWindow() )
198 SUIT_ViewWindow* win = desktop->activeWindow();
199 if ( !win || !win->getViewManager() )
202 SUIT_Study* study = win->getViewManager()->study();
206 return study->application();
212 Returns the resource manager for the specified application name.
214 SUIT_ResourceMgr* SUIT_Session::resourceMgr() const
220 Removes the application from the list of launched applications.
221 If it is a last application the session will be closed.
223 void SUIT_Session::onApplicationClosed( SUIT_Application* theApp )
225 emit applicationClosed( theApp );
227 myAppList.remove( theApp );
228 if ( theApp == myActiveApp )
231 if ( myAppList.isEmpty() )
233 printf( "Calling QApplication::exit() with exit code = %d\n", myExitStatus );
234 qApp->exit( myExitStatus );
239 Destroys session by closing all applications.
241 void SUIT_Session::closeSession( int mode, int flags )
243 while ( !myAppList.isEmpty() )
245 SUIT_Application* app = myAppList.getFirst();
246 bool closePermanently;
247 if ( mode == ASK && !app->isPossibleToClose( closePermanently ) )
249 else if ( mode == SAVE )
251 SUIT_Study* study = app->activeStudy();
252 if ( study->isModified() && study->isSaved() )
253 study->saveDocument();
255 else if ( mode == DONT_SAVE )
257 myExitStatus = FORCED;
260 app->closeApplication();
266 Get session exit flags.
268 By default, exit flags are set to 0. You can use pass any flags to the
269 closeSession() method if you need to process them later on application
274 int SUIT_Session::exitFlags() const
279 /*! \retval return myHandler*/
280 SUIT_ExceptionHandler* SUIT_Session::handler() const
285 /*! \retval return last error string.*/
286 QString SUIT_Session::lastError() const
291 ::FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
292 FORMAT_MESSAGE_IGNORE_INSERTS, 0, ::GetLastError(), 0, (LPTSTR)&lpMsgBuf, 0, 0 );
293 str = QString( (LPTSTR)lpMsgBuf );
294 LocalFree( lpMsgBuf );
296 str = QString( dlerror() );
301 /*! Load library to session.
302 * \retval Loaded library.
304 SUIT_Session::AppLib SUIT_Session::loadLibrary( const QString& name, QString& libName )
306 QString libFile = SUIT_Tools::library( name );
309 if ( libFile.isEmpty() )
314 lib = ::LoadLibrary( (char*)libFile.latin1() );
316 lib = dlopen( (char*)libFile.latin1(), RTLD_LAZY | RTLD_GLOBAL );
321 /*! \retval Return file name by application name.*/
322 QString SUIT_Session::applicationName( const QString& str ) const
325 return SUIT_Tools::file( str, false );
327 QString fileName = SUIT_Tools::file( str, false );
328 if ( fileName.startsWith( "lib" ) )
329 fileName = fileName.right( fileName.length() - 3 );
335 Virtual method, creates an instance of ResourceManager
337 SUIT_ResourceMgr* SUIT_Session::createResourceMgr( const QString& appName ) const
339 return new SUIT_ResourceMgr( applicationName( appName ) );
343 Slot, called on activation of some application's desktop
345 void SUIT_Session::onApplicationActivated( SUIT_Application* app )
351 \retval Return TRUE, if a command is currently executed in Python Console,
354 bool SUIT_Session::IsPythonExecuted()
357 SUIT_Session_PythonMutex.lock();
358 ret = SUIT_Session_IsPythonExecuted;
359 SUIT_Session_PythonMutex.unlock();
364 Set value of boolean flag, being returned by method \a IsPythonExecuted().
365 It is supposed to set the flag to TRUE when any python command starts
366 and reset it to FALSE when the command finishes.
368 void SUIT_Session::SetPythonExecuted(bool isPythonExecuted)
370 SUIT_Session_PythonMutex.lock();
371 SUIT_Session_IsPythonExecuted = isPythonExecuted;
372 SUIT_Session_PythonMutex.unlock();