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;
328 str = QString::fromWCharArray(msg);
330 str = QString( SUIT_Tools::toQString( msg ) );
332 LocalFree( lpMsgBuf );
334 str = QString( dlerror() );
339 /*! Load library to session.
340 * \retval Loaded library.
342 SUIT_Session::AppLib SUIT_Session::loadLibrary( const QString& name, QString& libName )
344 QString libFile = SUIT_Tools::library( name );
347 if ( libFile.isEmpty() )
351 QByteArray bid = libFile.toUtf8();
354 LPTSTR str = (LPTSTR)libFile.utf16();
356 LPTSTR str = (LPTSTR)(const char*)bid;
358 lib = ::LoadLibrary( str );
360 lib = dlopen( (const char*)libFile.toUtf8(), RTLD_LAZY | RTLD_GLOBAL );
365 /*! \retval Return file name by application name.*/
366 QString SUIT_Session::applicationName( const QString& str ) const
369 return SUIT_Tools::file( str, false );
371 QString fileName = SUIT_Tools::file( str, false );
372 if ( fileName.startsWith( "lib" ) )
373 fileName = fileName.right( fileName.length() - 3 );
379 Virtual method, creates an instance of ResourceManager
381 SUIT_ResourceMgr* SUIT_Session::createResourceMgr( const QString& appName ) const
383 return new SUIT_ResourceMgr( applicationName( appName ) );
387 Slot, called on activation of some application's desktop
389 void SUIT_Session::onApplicationActivated( SUIT_Application* app )