Back to index

salome-gui  6.5.0
SUIT_Session.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 #include "SUIT_Session.h"
00024 
00025 #include "SUIT_Study.h"
00026 #include "SUIT_Tools.h"
00027 #include "SUIT_MessageBox.h"
00028 #include "SUIT_ExceptionHandler.h"
00029 #include "SUIT_ResourceMgr.h"
00030 
00031 #include <QApplication>
00032 
00033 #ifdef WIN32
00034 #include <windows.h>
00035 #else
00036 #include <dlfcn.h>
00037 #endif
00038 
00039 SUIT_Session* SUIT_Session::mySession = 0;
00040 
00043 SUIT_Session::SUIT_Session()
00044 : QObject(),
00045   myResMgr( 0 ),
00046   myActiveApp( 0 ),
00047   myHandler( 0 ),
00048   myExitStatus( NORMAL ),
00049   myExitFlags ( 0 )
00050 {
00051   SUIT_ASSERT( !mySession )
00052 
00053   mySession = this;
00054 }
00055 
00057 SUIT_Session::~SUIT_Session()
00058 {
00059   for ( AppList::iterator it = myAppList.begin(); it != myAppList.end(); ++it )
00060     delete *it;
00061 
00062   myAppList.clear();
00063 
00064   if ( myResMgr )
00065   {
00066     delete myResMgr;
00067     myResMgr = 0;
00068   }
00069   mySession = 0;
00070 }
00071 
00073 SUIT_Session* SUIT_Session::session()
00074 {
00075   return mySession;
00076 }
00077 
00082 SUIT_Application* SUIT_Session::startApplication( const QString& name, int /*args*/, char** /*argv*/ )
00083 {
00084   AppLib libHandle = 0;
00085 
00086   QString appName = applicationName( name );
00087   if ( myAppLibs.contains( appName ) )
00088     libHandle = myAppLibs[appName];
00089 
00090   QString lib;
00091   if ( !libHandle )
00092     libHandle = loadLibrary( name, lib );
00093 
00094   if ( !libHandle )
00095   {
00096     SUIT_MessageBox::warning( 0, tr( "Error" ),
00097                               tr( "Can not load application library \"%1\": %2").arg( lib ).arg( lastError() ) );
00098     return 0;
00099   }
00100 
00101   if ( !myAppLibs.contains( appName ) || !myAppLibs[appName] ) // jfa 22.06.2005
00102     myAppLibs.insert( appName, libHandle );
00103 
00104   APP_CREATE_FUNC crtInst = 0;
00105 
00106 #ifdef WIN32
00107   crtInst = (APP_CREATE_FUNC)::GetProcAddress( (HINSTANCE)libHandle, APP_CREATE_NAME );
00108 #else
00109   crtInst = (APP_CREATE_FUNC)dlsym( libHandle, APP_CREATE_NAME );
00110 #endif
00111 
00112   if ( !crtInst )
00113   {
00114     SUIT_MessageBox::warning( 0, tr( "Error" ),
00115                               tr( "Can not find function \"%1\": %2" ).arg( APP_CREATE_NAME ).arg( lastError() ) );
00116     return 0;
00117   }
00118 
00119   // Prepare Resource Manager for the new application if it doesn't exist yet
00120   if ( !myResMgr )
00121   {
00122     myResMgr = createResourceMgr( appName );
00123     myResMgr->loadLanguage();
00124   }
00125 
00126   //jfa 22.06.2005:SUIT_Application* anApp = crtInst( args, argv );
00127   SUIT_Application* anApp = crtInst();
00128   if ( !anApp )
00129   {
00130     SUIT_MessageBox::warning( 0, tr( "Error" ), tr( "Can not create application \"%1\": %2").arg( appName ).arg( lastError() ) );
00131     return 0;
00132   }
00133 
00134   anApp->setObjectName( appName );
00135 
00136   insertApplication( anApp );
00137 
00138   if ( !myHandler )
00139   {
00140     APP_GET_HANDLER_FUNC crtHndlr = 0;
00141 #ifdef WIN32
00142     crtHndlr = (APP_GET_HANDLER_FUNC)::GetProcAddress( (HINSTANCE)libHandle, APP_GET_HANDLER_NAME );
00143 #else
00144     crtHndlr = (APP_GET_HANDLER_FUNC)dlsym( libHandle, APP_GET_HANDLER_NAME );
00145 #endif
00146     if ( crtHndlr )
00147       myHandler = crtHndlr();
00148   }
00149 
00150   anApp->start();
00151 
00152   // Application can be closed during starting (not started).
00153   if ( !myAppList.contains( anApp ) )
00154     anApp = 0;
00155 
00156   return anApp;
00157 }
00158 
00162 QList<SUIT_Application*> SUIT_Session::applications() const
00163 {
00164   return myAppList;
00165 }
00166 
00167 void SUIT_Session::insertApplication( SUIT_Application* app )
00168 {
00169   if ( !app || myAppList.contains( app ) )
00170     return;
00171 
00172   myAppList.append( app );
00173 
00174   connect( app, SIGNAL( applicationClosed( SUIT_Application* ) ),
00175            this, SLOT( onApplicationClosed( SUIT_Application* ) ) );
00176   connect( app, SIGNAL( activated( SUIT_Application* ) ), 
00177                  this, SLOT( onApplicationActivated( SUIT_Application* ) ) );
00178 }
00179 
00183 SUIT_Application* SUIT_Session::activeApplication() const
00184 {
00185   /*
00186   if ( myAppList.count() == 1 )
00187     return myAppList.getFirst();
00188 
00189   SUIT_Desktop* desktop = 0;
00190   for ( AppListIterator it( myAppList ); it.current() && !desktop; ++it )
00191   {
00192     SUIT_Desktop* desk = it.current()->desktop();
00193     if ( desk && desk->isActiveWindow() )
00194       desktop = desk;
00195   }
00196 
00197   if ( !desktop )
00198     return 0;
00199 
00200   SUIT_ViewWindow* win = desktop->activeWindow();
00201   if ( !win || !win->getViewManager() )
00202     return 0;
00203 
00204   SUIT_Study* study = win->getViewManager()->study();
00205   if ( !study )
00206     return 0;
00207 
00208   return study->application();
00209   */
00210   return myActiveApp;
00211 }
00212 
00216 SUIT_ResourceMgr* SUIT_Session::resourceMgr() const
00217 {
00218   return myResMgr;
00219 }
00220 
00225 void SUIT_Session::onApplicationClosed( SUIT_Application* theApp )
00226 {
00227   emit applicationClosed( theApp );
00228 
00229   myAppList.removeAll( theApp );
00230   delete theApp;
00231 
00232   if ( theApp == myActiveApp )
00233     myActiveApp = 0;
00234 
00235   if ( myAppList.isEmpty() )
00236   {
00237     //printf( "Calling QApplication::exit() with exit code = %d\n", myExitStatus );
00238     QApplication::instance()->exit( myExitStatus );
00239   }
00240 }
00241 
00245 void SUIT_Session::closeSession( int mode, int flags )
00246 {
00247   AppList apps = myAppList;
00248   for ( AppList::const_iterator it = apps.begin(); it != apps.end(); ++it )
00249   {
00250     SUIT_Application* app = *it;
00251     bool closePermanently;
00252     if ( mode == ASK && !app->isPossibleToClose( closePermanently ) )
00253       return;
00254     else if ( mode == SAVE )
00255     {
00256       SUIT_Study* study = app->activeStudy();
00257       if ( study->isModified() && study->isSaved() )
00258               study->saveDocument();
00259     }
00260     else if ( mode == DONT_SAVE )
00261     {
00262       myExitStatus = FORCED;
00263     }
00264 
00265     app->closeApplication();
00266   }
00267 
00268   myExitFlags = flags;
00269 }
00270 
00280 int SUIT_Session::exitFlags() const
00281 {
00282   return myExitFlags;
00283 }
00284 
00286 SUIT_ExceptionHandler* SUIT_Session::handler() const
00287 {
00288   return myHandler;
00289 }
00290 
00292 QString SUIT_Session::lastError() const
00293 {
00294   QString str;
00295 #ifdef WIN32
00296   LPVOID lpMsgBuf;
00297   ::FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
00298                    FORMAT_MESSAGE_IGNORE_INSERTS, 0, ::GetLastError(), 0, (LPTSTR)&lpMsgBuf, 0, 0 );
00299   LPTSTR msg = (LPTSTR)lpMsgBuf;
00300   str = QString( SUIT_Tools::toQString( msg ) );
00301   LocalFree( lpMsgBuf );
00302 #else
00303   str = QString( dlerror() );
00304 #endif
00305   return str;
00306 }
00307 
00311 SUIT_Session::AppLib SUIT_Session::loadLibrary( const QString& name, QString& libName )
00312 {
00313   QString libFile = SUIT_Tools::library( name );
00314 
00315   libName = libFile;
00316   if ( libFile.isEmpty() )
00317     return 0;
00318 
00319   AppLib lib = 0;
00320   QByteArray bid = libFile.toLatin1();
00321 #ifdef WIN32
00322 #ifdef UNICODE
00323   LPTSTR str = (LPTSTR)libFile.utf16();
00324 #else
00325   LPTSTR str = (LPTSTR)(const char*)bid;
00326 #endif
00327   lib = ::LoadLibrary( str );
00328 #else
00329   lib = dlopen( (const char*)libFile.toLatin1(), RTLD_LAZY | RTLD_GLOBAL  );
00330 #endif
00331   return lib;
00332 }
00333 
00335 QString SUIT_Session::applicationName( const QString& str ) const
00336 {
00337 #ifdef WIN32
00338   return SUIT_Tools::file( str, false );
00339 #else
00340   QString fileName = SUIT_Tools::file( str, false );
00341   if ( fileName.startsWith( "lib" ) )
00342     fileName = fileName.right( fileName.length() - 3 );
00343   return fileName;
00344 #endif
00345 }
00346 
00350 SUIT_ResourceMgr* SUIT_Session::createResourceMgr( const QString& appName ) const
00351 {
00352   return new SUIT_ResourceMgr( applicationName( appName ) );
00353 }
00354 
00358 void SUIT_Session::onApplicationActivated( SUIT_Application* app ) 
00359 {
00360   myActiveApp = app;
00361 }