1 // Copyright (C) 2007-2008 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
22 #include "SUIT_Session.h"
24 #include "SUIT_Study.h"
25 #include "SUIT_Tools.h"
26 #include "SUIT_MessageBox.h"
27 #include "SUIT_ExceptionHandler.h"
28 #include "SUIT_ResourceMgr.h"
30 #include <QApplication>
38 SUIT_Session* SUIT_Session::mySession = 0;
42 SUIT_Session::SUIT_Session()
47 myExitStatus( NORMAL ),
50 SUIT_ASSERT( !mySession )
55 /*!destructor. Clear applications list and set mySession to zero.*/
56 SUIT_Session::~SUIT_Session()
58 for ( AppList::iterator it = myAppList.begin(); it != myAppList.end(); ++it )
71 /*! \retval return mySession */
72 SUIT_Session* SUIT_Session::session()
78 Starts new application using "createApplication" function of loaded DLL.
81 SUIT_Application* SUIT_Session::startApplication( const QString& name, int /*args*/, char** /*argv*/ )
85 QString appName = applicationName( name );
86 if ( myAppLibs.contains( appName ) )
87 libHandle = myAppLibs[appName];
91 libHandle = loadLibrary( name, lib );
95 SUIT_MessageBox::warning( 0, tr( "Error" ),
96 tr( "Can not load application library \"%1\": %2").arg( lib ).arg( lastError() ) );
100 if ( !myAppLibs.contains( appName ) || !myAppLibs[appName] ) // jfa 22.06.2005
101 myAppLibs.insert( appName, libHandle );
103 APP_CREATE_FUNC crtInst = 0;
106 crtInst = (APP_CREATE_FUNC)::GetProcAddress( (HINSTANCE)libHandle, APP_CREATE_NAME );
108 crtInst = (APP_CREATE_FUNC)dlsym( libHandle, APP_CREATE_NAME );
113 SUIT_MessageBox::warning( 0, tr( "Error" ),
114 tr( "Can not find function \"%1\": %2" ).arg( APP_CREATE_NAME ).arg( lastError() ) );
118 // Prepare Resource Manager for the new application if it doesn't exist yet
121 myResMgr = createResourceMgr( appName );
122 myResMgr->loadLanguage();
125 //jfa 22.06.2005:SUIT_Application* anApp = crtInst( args, argv );
126 SUIT_Application* anApp = crtInst();
129 SUIT_MessageBox::warning( 0, tr( "Error" ), tr( "Can not create application \"%1\": %2").arg( appName ).arg( lastError() ) );
133 anApp->setObjectName( appName );
135 insertApplication( anApp );
139 APP_GET_HANDLER_FUNC crtHndlr = 0;
141 crtHndlr = (APP_GET_HANDLER_FUNC)::GetProcAddress( (HINSTANCE)libHandle, APP_GET_HANDLER_NAME );
143 crtHndlr = (APP_GET_HANDLER_FUNC)dlsym( libHandle, APP_GET_HANDLER_NAME );
146 myHandler = crtHndlr();
151 // Application can be closed during starting (not started).
152 if ( !myAppList.contains( anApp ) )
159 Gets the list of all applications
161 QList<SUIT_Application*> SUIT_Session::applications() const
166 void SUIT_Session::insertApplication( SUIT_Application* app )
168 if ( !app || myAppList.contains( app ) )
171 myAppList.append( app );
173 connect( app, SIGNAL( applicationClosed( SUIT_Application* ) ),
174 this, SLOT( onApplicationClosed( SUIT_Application* ) ) );
175 connect( app, SIGNAL( activated( SUIT_Application* ) ),
176 this, SLOT( onApplicationActivated( SUIT_Application* ) ) );
180 Returns the active application
182 SUIT_Application* SUIT_Session::activeApplication() const
185 if ( myAppList.count() == 1 )
186 return myAppList.getFirst();
188 SUIT_Desktop* desktop = 0;
189 for ( AppListIterator it( myAppList ); it.current() && !desktop; ++it )
191 SUIT_Desktop* desk = it.current()->desktop();
192 if ( desk && desk->isActiveWindow() )
199 SUIT_ViewWindow* win = desktop->activeWindow();
200 if ( !win || !win->getViewManager() )
203 SUIT_Study* study = win->getViewManager()->study();
207 return study->application();
213 Returns the resource manager for the specified application name.
215 SUIT_ResourceMgr* SUIT_Session::resourceMgr() const
221 Removes the application from the list of launched applications.
222 If it is a last application the session will be closed.
224 void SUIT_Session::onApplicationClosed( SUIT_Application* theApp )
226 emit applicationClosed( theApp );
228 myAppList.removeAll( theApp );
231 if ( theApp == myActiveApp )
234 if ( myAppList.isEmpty() )
236 //printf( "Calling QApplication::exit() with exit code = %d\n", myExitStatus );
237 QApplication::instance()->exit( myExitStatus );
242 Destroys session by closing all applications.
244 void SUIT_Session::closeSession( int mode, int flags )
246 AppList apps = myAppList;
247 for ( AppList::const_iterator it = apps.begin(); it != apps.end(); ++it )
249 SUIT_Application* app = *it;
250 bool closePermanently;
251 if ( mode == ASK && !app->isPossibleToClose( closePermanently ) )
253 else if ( mode == SAVE )
255 SUIT_Study* study = app->activeStudy();
256 if ( study->isModified() && study->isSaved() )
257 study->saveDocument();
259 else if ( mode == DONT_SAVE )
261 myExitStatus = FORCED;
264 app->closeApplication();
271 Get session exit flags.
273 By default, exit flags are set to 0. You can use pass any flags to the
274 closeSession() method if you need to process them later on application
279 int SUIT_Session::exitFlags() const
284 /*! \retval return myHandler*/
285 SUIT_ExceptionHandler* SUIT_Session::handler() const
290 /*! \retval return last error string.*/
291 QString SUIT_Session::lastError() const
296 ::FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
297 FORMAT_MESSAGE_IGNORE_INSERTS, 0, ::GetLastError(), 0, (LPTSTR)&lpMsgBuf, 0, 0 );
298 LPTSTR msg = (LPTSTR)lpMsgBuf;
299 str = QString( SUIT_Tools::toQString( msg ) );
300 LocalFree( lpMsgBuf );
302 str = QString( dlerror() );
307 /*! Load library to session.
308 * \retval Loaded library.
310 SUIT_Session::AppLib SUIT_Session::loadLibrary( const QString& name, QString& libName )
312 QString libFile = SUIT_Tools::library( name );
315 if ( libFile.isEmpty() )
319 QByteArray bid = libFile.toLatin1();
322 LPTSTR str = (LPTSTR)libFile.utf16();
324 LPTSTR str = (LPTSTR)(const char*)bid;
326 lib = ::LoadLibrary( str );
328 lib = dlopen( (const char*)libFile.toLatin1(), RTLD_LAZY | RTLD_GLOBAL );
333 /*! \retval Return file name by application name.*/
334 QString SUIT_Session::applicationName( const QString& str ) const
337 return SUIT_Tools::file( str, false );
339 QString fileName = SUIT_Tools::file( str, false );
340 if ( fileName.startsWith( "lib" ) )
341 fileName = fileName.right( fileName.length() - 3 );
347 Virtual method, creates an instance of ResourceManager
349 SUIT_ResourceMgr* SUIT_Session::createResourceMgr( const QString& appName ) const
351 return new SUIT_ResourceMgr( applicationName( appName ) );
355 Slot, called on activation of some application's desktop
357 void SUIT_Session::onApplicationActivated( SUIT_Application* app )