1 // Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #include "SUIT_Session.h"
25 #include "SUIT_Study.h"
26 #include "SUIT_Tools.h"
27 #include "SUIT_MessageBox.h"
28 #include "SUIT_ExceptionHandler.h"
29 #include "SUIT_ResourceMgr.h"
31 #include <QApplication>
39 SUIT_Session* SUIT_Session::mySession = 0;
43 SUIT_Session::SUIT_Session()
48 myExitStatus( NORMAL ),
51 SUIT_ASSERT( !mySession )
56 SUIT_Session::SUIT_Session( int argc, char** argv )
61 myExitStatus( NORMAL ),
64 SUIT_ASSERT( !mySession )
68 for ( int i = 0; i < argc; i++ )
69 myArguments << QString( argv[i] );
72 /*!destructor. Clear applications list and set mySession to zero.*/
73 SUIT_Session::~SUIT_Session()
75 for ( AppList::iterator it = myAppList.begin(); it != myAppList.end(); ++it )
89 Get arguments of the current session
91 QStringList SUIT_Session::arguments()
94 if ( !myArguments.isEmpty() ) r = myArguments;
95 else if ( QApplication::instance() ) r = QApplication::arguments();
99 /*! \retval return mySession */
100 SUIT_Session* SUIT_Session::session()
106 Starts new application using "createApplication" function of loaded DLL.
109 SUIT_Application* SUIT_Session::startApplication( const QString& name, int /*args*/, char** /*argv*/ )
111 AppLib libHandle = 0;
113 QString appName = applicationName( name );
114 if ( myAppLibs.contains( appName ) )
115 libHandle = myAppLibs[appName];
119 libHandle = loadLibrary( name, lib );
123 SUIT_MessageBox::warning( 0, tr( "Error" ),
124 tr( "Can not load application library \"%1\": %2").arg( lib ).arg( lastError() ) );
128 if ( !myAppLibs.contains( appName ) || !myAppLibs[appName] ) // jfa 22.06.2005
129 myAppLibs.insert( appName, libHandle );
131 APP_CREATE_FUNC crtInst = 0;
134 crtInst = (APP_CREATE_FUNC)::GetProcAddress( (HINSTANCE)libHandle, APP_CREATE_NAME );
136 crtInst = (APP_CREATE_FUNC)dlsym( libHandle, APP_CREATE_NAME );
141 SUIT_MessageBox::warning( 0, tr( "Error" ),
142 tr( "Can not find function \"%1\": %2" ).arg( APP_CREATE_NAME ).arg( lastError() ) );
146 // Prepare Resource Manager for the new application if it doesn't exist yet
149 myResMgr = createResourceMgr( appName );
150 myResMgr->loadLanguage();
153 //jfa 22.06.2005:SUIT_Application* anApp = crtInst( args, argv );
154 SUIT_Application* anApp = crtInst();
157 SUIT_MessageBox::warning( 0, tr( "Error" ), tr( "Can not create application \"%1\": %2").arg( appName ).arg( lastError() ) );
161 anApp->setObjectName( appName );
163 insertApplication( anApp );
167 APP_GET_HANDLER_FUNC crtHndlr = 0;
169 crtHndlr = (APP_GET_HANDLER_FUNC)::GetProcAddress( (HINSTANCE)libHandle, APP_GET_HANDLER_NAME );
171 crtHndlr = (APP_GET_HANDLER_FUNC)dlsym( libHandle, APP_GET_HANDLER_NAME );
174 myHandler = crtHndlr();
179 // Application can be closed during starting (not started).
180 if ( !myAppList.contains( anApp ) )
187 Gets the list of all applications
189 QList<SUIT_Application*> SUIT_Session::applications() const
194 void SUIT_Session::insertApplication( SUIT_Application* app )
196 if ( !app || myAppList.contains( app ) )
199 myAppList.append( app );
201 connect( app, SIGNAL( applicationClosed( SUIT_Application* ) ),
202 this, SLOT( onApplicationClosed( SUIT_Application* ) ) );
203 connect( app, SIGNAL( activated( SUIT_Application* ) ),
204 this, SLOT( onApplicationActivated( SUIT_Application* ) ) );
208 Returns the active application
210 SUIT_Application* SUIT_Session::activeApplication() const
213 if ( myAppList.count() == 1 )
214 return myAppList.getFirst();
216 SUIT_Desktop* desktop = 0;
217 for ( AppListIterator it( myAppList ); it.current() && !desktop; ++it )
219 SUIT_Desktop* desk = it.current()->desktop();
220 if ( desk && desk->isActiveWindow() )
227 SUIT_ViewWindow* win = desktop->activeWindow();
228 if ( !win || !win->getViewManager() )
231 SUIT_Study* study = win->getViewManager()->study();
235 return study->application();
241 Returns the resource manager for the specified application name.
243 SUIT_ResourceMgr* SUIT_Session::resourceMgr() const
249 Removes the application from the list of launched applications.
250 If it is a last application the session will be closed.
252 void SUIT_Session::onApplicationClosed( SUIT_Application* theApp )
254 emit applicationClosed( theApp );
256 myAppList.removeAll( theApp );
259 if ( theApp == myActiveApp )
262 if ( myAppList.isEmpty() )
264 //printf( "Calling QApplication::exit() with exit code = %d\n", myExitStatus );
265 QApplication::instance()->exit( myExitStatus );
270 Destroys session by closing all applications.
272 void SUIT_Session::closeSession( int mode, int flags )
274 AppList apps = myAppList;
275 for ( AppList::const_iterator it = apps.begin(); it != apps.end(); ++it )
277 SUIT_Application* app = *it;
278 bool closePermanently;
279 if ( mode == ASK && !app->isPossibleToClose( closePermanently ) )
281 else if ( mode == SAVE )
283 SUIT_Study* study = app->activeStudy();
284 if ( study->isModified() && study->isSaved() )
285 study->saveDocument();
287 else if ( mode == DONT_SAVE )
289 myExitStatus = FORCED;
292 app->closeApplication();
299 Get session exit flags.
301 By default, exit flags are set to 0. You can use pass any flags to the
302 closeSession() method if you need to process them later on application
307 int SUIT_Session::exitFlags() const
312 /*! \retval return myHandler*/
313 SUIT_ExceptionHandler* SUIT_Session::handler() const
318 /*! \retval return last error string.*/
319 QString SUIT_Session::lastError() const
324 ::FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
325 FORMAT_MESSAGE_IGNORE_INSERTS, 0, ::GetLastError(), 0, (LPTSTR)&lpMsgBuf, 0, 0 );
326 LPTSTR msg = (LPTSTR)lpMsgBuf;
327 str = QString( SUIT_Tools::toQString( msg ) );
328 LocalFree( lpMsgBuf );
330 str = QString( dlerror() );
335 /*! Load library to session.
336 * \retval Loaded library.
338 SUIT_Session::AppLib SUIT_Session::loadLibrary( const QString& name, QString& libName )
340 QString libFile = SUIT_Tools::library( name );
343 if ( libFile.isEmpty() )
347 QByteArray bid = libFile.toLatin1();
350 LPTSTR str = (LPTSTR)libFile.utf16();
352 LPTSTR str = (LPTSTR)(const char*)bid;
354 lib = ::LoadLibrary( str );
356 lib = dlopen( (const char*)libFile.toLatin1(), RTLD_LAZY | RTLD_GLOBAL );
361 /*! \retval Return file name by application name.*/
362 QString SUIT_Session::applicationName( const QString& str ) const
365 return SUIT_Tools::file( str, false );
367 QString fileName = SUIT_Tools::file( str, false );
368 if ( fileName.startsWith( "lib" ) )
369 fileName = fileName.right( fileName.length() - 3 );
375 Virtual method, creates an instance of ResourceManager
377 SUIT_ResourceMgr* SUIT_Session::createResourceMgr( const QString& appName ) const
379 return new SUIT_ResourceMgr( applicationName( appName ) );
383 Slot, called on activation of some application's desktop
385 void SUIT_Session::onApplicationActivated( SUIT_Application* app )