1 // Copyright (C) 2007-2013 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.
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 /*!destructor. Clear applications list and set mySession to zero.*/
57 SUIT_Session::~SUIT_Session()
59 for ( AppList::iterator it = myAppList.begin(); it != myAppList.end(); ++it )
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::warning( 0, tr( "Error" ),
97 tr( "Can not load application library \"%1\": %2").arg( lib ).arg( lastError() ) );
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( (HINSTANCE)libHandle, APP_CREATE_NAME );
109 crtInst = (APP_CREATE_FUNC)dlsym( libHandle, APP_CREATE_NAME );
114 SUIT_MessageBox::warning( 0, tr( "Error" ),
115 tr( "Can not find function \"%1\": %2" ).arg( APP_CREATE_NAME ).arg( lastError() ) );
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::warning( 0, tr( "Error" ), tr( "Can not create application \"%1\": %2").arg( appName ).arg( lastError() ) );
134 anApp->setObjectName( appName );
136 insertApplication( anApp );
140 APP_GET_HANDLER_FUNC crtHndlr = 0;
142 crtHndlr = (APP_GET_HANDLER_FUNC)::GetProcAddress( (HINSTANCE)libHandle, APP_GET_HANDLER_NAME );
144 crtHndlr = (APP_GET_HANDLER_FUNC)dlsym( libHandle, APP_GET_HANDLER_NAME );
147 myHandler = crtHndlr();
152 // Application can be closed during starting (not started).
153 if ( !myAppList.contains( anApp ) )
160 Gets the list of all applications
162 QList<SUIT_Application*> SUIT_Session::applications() const
167 void SUIT_Session::insertApplication( SUIT_Application* app )
169 if ( !app || myAppList.contains( app ) )
172 myAppList.append( app );
174 connect( app, SIGNAL( applicationClosed( SUIT_Application* ) ),
175 this, SLOT( onApplicationClosed( SUIT_Application* ) ) );
176 connect( app, SIGNAL( activated( SUIT_Application* ) ),
177 this, SLOT( onApplicationActivated( SUIT_Application* ) ) );
181 Returns the active application
183 SUIT_Application* SUIT_Session::activeApplication() const
186 if ( myAppList.count() == 1 )
187 return myAppList.getFirst();
189 SUIT_Desktop* desktop = 0;
190 for ( AppListIterator it( myAppList ); it.current() && !desktop; ++it )
192 SUIT_Desktop* desk = it.current()->desktop();
193 if ( desk && desk->isActiveWindow() )
200 SUIT_ViewWindow* win = desktop->activeWindow();
201 if ( !win || !win->getViewManager() )
204 SUIT_Study* study = win->getViewManager()->study();
208 return study->application();
214 Returns the resource manager for the specified application name.
216 SUIT_ResourceMgr* SUIT_Session::resourceMgr() const
222 Removes the application from the list of launched applications.
223 If it is a last application the session will be closed.
225 void SUIT_Session::onApplicationClosed( SUIT_Application* theApp )
227 emit applicationClosed( theApp );
229 myAppList.removeAll( theApp );
232 if ( theApp == myActiveApp )
235 if ( myAppList.isEmpty() )
237 //printf( "Calling QApplication::exit() with exit code = %d\n", myExitStatus );
238 QApplication::instance()->exit( myExitStatus );
243 Destroys session by closing all applications.
245 void SUIT_Session::closeSession( int mode, int flags )
247 AppList apps = myAppList;
248 for ( AppList::const_iterator it = apps.begin(); it != apps.end(); ++it )
250 SUIT_Application* app = *it;
251 bool closePermanently;
252 if ( mode == ASK && !app->isPossibleToClose( closePermanently ) )
254 else if ( mode == SAVE )
256 SUIT_Study* study = app->activeStudy();
257 if ( study->isModified() && study->isSaved() )
258 study->saveDocument();
260 else if ( mode == DONT_SAVE )
262 myExitStatus = FORCED;
265 app->closeApplication();
272 Get session exit flags.
274 By default, exit flags are set to 0. You can use pass any flags to the
275 closeSession() method if you need to process them later on application
280 int SUIT_Session::exitFlags() const
285 /*! \retval return myHandler*/
286 SUIT_ExceptionHandler* SUIT_Session::handler() const
291 /*! \retval return last error string.*/
292 QString SUIT_Session::lastError() const
297 ::FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
298 FORMAT_MESSAGE_IGNORE_INSERTS, 0, ::GetLastError(), 0, (LPTSTR)&lpMsgBuf, 0, 0 );
299 LPTSTR msg = (LPTSTR)lpMsgBuf;
300 str = QString( SUIT_Tools::toQString( msg ) );
301 LocalFree( lpMsgBuf );
303 str = QString( dlerror() );
308 /*! Load library to session.
309 * \retval Loaded library.
311 SUIT_Session::AppLib SUIT_Session::loadLibrary( const QString& name, QString& libName )
313 QString libFile = SUIT_Tools::library( name );
316 if ( libFile.isEmpty() )
320 QByteArray bid = libFile.toLatin1();
323 LPTSTR str = (LPTSTR)libFile.utf16();
325 LPTSTR str = (LPTSTR)(const char*)bid;
327 lib = ::LoadLibrary( str );
329 lib = dlopen( (const char*)libFile.toLatin1(), RTLD_LAZY | RTLD_GLOBAL );
334 /*! \retval Return file name by application name.*/
335 QString SUIT_Session::applicationName( const QString& str ) const
338 return SUIT_Tools::file( str, false );
340 QString fileName = SUIT_Tools::file( str, false );
341 if ( fileName.startsWith( "lib" ) )
342 fileName = fileName.right( fileName.length() - 3 );
348 Virtual method, creates an instance of ResourceManager
350 SUIT_ResourceMgr* SUIT_Session::createResourceMgr( const QString& appName ) const
352 return new SUIT_ResourceMgr( applicationName( appName ) );
356 Slot, called on activation of some application's desktop
358 void SUIT_Session::onApplicationActivated( SUIT_Application* app )