1 // Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
8 // This library is distributed in the hope that it will be useful
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 #include "CAM_Application.h"
21 #include "CAM_Study.h"
22 #include "CAM_Module.h"
24 #include <SUIT_Tools.h>
25 #include <SUIT_Session.h>
26 #include <SUIT_MessageBox.h>
29 #include <qfileinfo.h>
30 #include <qtextstream.h>
33 #include <qapplication.h>
42 /*!Create new instance of CAM_Application*/
43 extern "C" CAM_EXPORT SUIT_Application* createApplication()
45 return new CAM_Application();
48 /*!Constructor. read module list.
49 * \param autoLoad - auto load flag.
51 CAM_Application::CAM_Application( const bool autoLoad )
54 myAutoLoad( autoLoad )
59 /*!Destructor. Do nothing.*/
60 CAM_Application::~CAM_Application()
64 /*! Load modules, if \a myAutoLoad flag is true.\n
65 * Start application - call start() method from parent class.
67 void CAM_Application::start()
72 STD_Application::start();
76 * \retval CAM_Module - active module.
78 CAM_Module* CAM_Application::activeModule() const
83 /*!Get module with name \a modName from modules list.
84 * \retval CAM_Module pointer - module.
86 CAM_Module* CAM_Application::module( const QString& modName ) const
89 for ( ModuleListIterator it( myModules ); it.current() && !mod; ++it )
90 if ( it.current()->moduleName() == modName )
95 /*!Gets modules iterator.*/
96 CAM_Application::ModuleListIterator CAM_Application::modules() const
98 return ModuleListIterator( myModules );
101 /*!Gets modules list.
102 * \param out - output list of modules.
104 void CAM_Application::modules( CAM_Application::ModuleList& out ) const
106 out.setAutoDelete( false );
109 for ( ModuleListIterator it( myModules ); it.current(); ++it )
110 out.append( it.current() );
113 /*!Gets list of names for modules.\n
114 * Get loaded modules names, if \a loaded is true, else \n
115 * get names from information list.
116 * \param lst - output list of names.
117 * \param loaded - boolean flag.
119 void CAM_Application::modules( QStringList& lst, const bool loaded ) const
124 for ( ModuleListIterator it( myModules ); it.current(); ++it )
125 lst.append( it.current()->moduleName() );
127 for ( ModuleInfoList::const_iterator it = myInfoList.begin(); it != myInfoList.end(); ++it )
128 lst.append( (*it).title );
131 /*!Adding module \a mod to list.
132 *\param mod - module.
134 void CAM_Application::addModule( CAM_Module* mod )
136 if ( !mod || myModules.contains( mod ) )
139 mod->initialize( this );
141 QMap<CAM_Module*, int> map;
144 for ( ModuleInfoList::const_iterator it = myInfoList.begin(); it != myInfoList.end(); ++it )
146 if ( (*it).title == mod->moduleName() )
147 newList.append( mod );
150 CAM_Module* curMod = module( (*it).title );
152 newList.append( curMod );
154 if ( !newList.isEmpty() )
155 map.insert( newList.getLast(), 0 );
158 for ( ModuleListIterator itr( myModules ); itr.current(); ++itr )
160 if ( !map.contains( itr.current() ) )
161 newList.append( itr.current() );
164 if ( !map.contains( mod ) )
165 newList.append( mod );
172 /*!Load modules from information list.
173 * \warning If some of modules not loaded, error message appear on desktop.
175 void CAM_Application::loadModules()
177 for ( ModuleInfoList::const_iterator it = myInfoList.begin(); it != myInfoList.end(); ++it )
179 CAM_Module* mod = loadModule( (*it).title );
183 if ( desktop() && desktop()->isShown() )
184 SUIT_MessageBox::error1( desktop(), tr( "Loading modules" ),
185 tr( "Can not load module %1" ).arg( (*it).title ), tr( "Ok" ) );
187 qWarning( tr( "Can not load module %1" ).arg( (*it).title ).latin1() );
192 /*!Load module with name \a modName.
193 *\param modName - module name for loading.
194 *\warning If information list is empty.
195 *\warning If module library (for module with \a modName) is empty.
196 *\warning If module library is not loaded.
198 CAM_Module* CAM_Application::loadModule( const QString& modName )
200 if ( myInfoList.isEmpty() )
202 qWarning( tr( "Modules configuration is not defined." ) );
206 QString libName = moduleLibrary( modName );
207 if ( libName.isEmpty() )
209 qWarning( tr( "Information about module \"%1\" doesn't exist." ).arg( modName ) );
214 GET_MODULE_FUNC crtInst = 0;
217 HINSTANCE modLib = ::LoadLibrary( libName );
221 ::FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
222 FORMAT_MESSAGE_IGNORE_INSERTS, 0, ::GetLastError(), 0, (LPTSTR)&lpMsgBuf, 0, 0 );
223 err = QString( "Failed to load %1. %2" ).arg( libName ).arg( (LPTSTR)lpMsgBuf );
224 ::LocalFree( lpMsgBuf );
228 crtInst = (GET_MODULE_FUNC)::GetProcAddress( modLib, GET_MODULE_NAME );
232 ::FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
233 FORMAT_MESSAGE_IGNORE_INSERTS, 0, ::GetLastError(), 0, (LPTSTR)&lpMsgBuf, 0, 0 );
234 err = QString( "Failed to find %1 function. %2" ).arg( GET_MODULE_NAME ).arg( (LPTSTR)lpMsgBuf );
235 ::LocalFree( lpMsgBuf );
239 void* modLib = dlopen( (char*)libName.latin1(), RTLD_LAZY );
241 err = QString( "Can not load library %1. %2" ).arg( libName ).arg( dlerror() );
244 crtInst = (GET_MODULE_FUNC)dlsym( modLib, GET_MODULE_NAME );
246 err = QString( "Failed to find function %1. %2" ).arg( GET_MODULE_NAME ).arg( dlerror() );
250 CAM_Module* module = crtInst ? crtInst() : 0;
253 module->setModuleName( modName );
254 module->setName( moduleName( modName ) );
257 if ( !err.isEmpty() ) {
258 if ( desktop() && desktop()->isShown() )
259 SUIT_MessageBox::warn1( desktop(), tr( "Error" ), err, tr( "Ok" ) );
261 qWarning( err.latin1() );
267 /*! @name Activate module group. */
269 /*!Activate module with name \a modName.
270 *\param modName - module name.
271 *\ratval true, if module loaded and activated successful, else false.
273 bool CAM_Application::activateModule( const QString& modName )
275 if ( !modName.isEmpty() && !activeStudy() )
279 if ( !modName.isEmpty() )
281 CAM_Module* mod = module( modName );
282 if ( !mod && !moduleLibrary( modName ).isEmpty() )
284 mod = loadModule( modName );
289 res = activateModule( mod );
292 res = activateModule( 0 );
297 /*!Activate module \a mod
298 *\param mod - module for activation.
299 *\retval true - if all sucessful.
300 *\warning Error message if module not activated in active study.
302 bool CAM_Application::activateModule( CAM_Module* mod )
304 if ( mod && !activeStudy() )
307 if ( myModule == mod )
312 if ( !myModule->deactivateModule( activeStudy() ) )
320 // Connect the module to the active study
321 myModule->connectToStudy( dynamic_cast<CAM_Study*>( activeStudy() ) );
322 if ( !myModule->activateModule( activeStudy() ) )
324 myModule->setMenuShown( false );
325 myModule->setToolShown( false );
326 if ( desktop() && desktop()->isShown() )
327 SUIT_MessageBox::error1( desktop(), tr( "ERROR_TLT" ), tr( "ERROR_ACTIVATE_MODULE_MSG" ).arg( myModule->moduleName() ), tr( "BUT_OK" ) );
329 qWarning( tr( "ERROR_ACTIVATE_MODULE_MSG" ).arg( myModule->moduleName() ).latin1() );
335 updateCommandsStatus();
341 /*!Create new study for current application.
342 *\retval study pointer.
344 SUIT_Study* CAM_Application::createNewStudy()
346 return new CAM_Study( this );
349 /*!Update commands status for parent class and for current class(if module is active)*/
350 void CAM_Application::updateCommandsStatus()
352 STD_Application::updateCommandsStatus();
354 if ( activeModule() )
355 activeModule()->updateCommandsStatus();
358 /*!Close all modules in study \a theDoc.
359 *\param theDoc - study
361 void CAM_Application::beforeCloseDoc( SUIT_Study* theDoc )
363 for ( ModuleListIterator it( myModules ); it.current(); ++it )
364 it.current()->studyClosed( theDoc );
367 /*!Sets active study for parent class.
368 *\param study - study.
370 void CAM_Application::setActiveStudy( SUIT_Study* study )
372 STD_Application::setActiveStudy( study );
376 void CAM_Application::moduleAdded( CAM_Module* mod )
378 // CAM_Study* study = dynamic_cast<CAM_Study*>( activeStudy() );
382 // study->insertDataModel( mod->dataModel() );
385 /*!Gets module name by title \a title
386 *\param title - title name
387 *\retval QString module name.
389 QString CAM_Application::moduleName( const QString& title ) const
392 for ( ModuleInfoList::const_iterator it = myInfoList.begin(); it != myInfoList.end() && res.isEmpty(); ++it )
394 if ( (*it).title == title )
400 /*!Gets module title by module name \a name
401 *\param name - module name
402 *\retval QString module title.
404 QString CAM_Application::moduleTitle( const QString& name ) const
407 for ( ModuleInfoList::const_iterator it = myInfoList.begin(); it != myInfoList.end() && res.isEmpty(); ++it )
409 if ( (*it).name == name )
415 /*!Get library name for module with title \a title.
416 *\param title - module title name.
417 *\param full - boolean flag (if true - return full library name, else internal name)
418 *\retval QString - library name.
420 QString CAM_Application::moduleLibrary( const QString& title, const bool full ) const
423 for ( ModuleInfoList::const_iterator it = myInfoList.begin(); it != myInfoList.end() && res.isEmpty(); ++it )
425 if ( (*it).title == title )
426 res = (*it).internal;
428 if ( !res.isEmpty() && full )
429 res = SUIT_Tools::library( res );
433 /*!Read modules list*/
434 void CAM_Application::readModuleList()
436 if ( !myInfoList.isEmpty() )
439 SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
444 for (int i = 1; i < qApp->argc(); i++)
445 args.append( qApp->argv()[i] );
447 QRegExp rx("--modules\\s+\\(\\s*(.*)\\s*\\)");
448 rx.setMinimal( true );
449 if ( rx.search( args.join(" ") ) >= 0 && rx.capturedTexts().count() > 0 ) {
450 QString modules = rx.capturedTexts()[1];
451 QStringList mods = QStringList::split(":",modules,false);
452 for ( uint i = 0; i < mods.count(); i++ ) {
453 if ( !mods[i].stripWhiteSpace().isEmpty() )
454 modList.append( mods[i].stripWhiteSpace() );
457 if ( modList.isEmpty() ) {
458 QString mods = resMgr->stringValue( "launch", "modules", QString::null );
459 modList = QStringList::split( ",", mods );
462 for ( QStringList::const_iterator it = modList.begin(); it != modList.end(); ++it )
464 QString modName = (*it).stripWhiteSpace();
465 if ( modName.isEmpty() )
468 QString modTitle = resMgr->stringValue( *it, QString( "name" ), QString::null );
469 if ( modTitle.isEmpty() )
472 QString modLibrary = resMgr->stringValue( *it, QString( "library" ), QString::null ).stripWhiteSpace();
473 if ( !modLibrary.isEmpty() )
476 modLibrary = SUIT_Tools::file( modLibrary.stripWhiteSpace() );
477 libExt = QString( "so" );
478 if ( SUIT_Tools::extension( modLibrary ).lower() == libExt )
479 modLibrary = modLibrary.mid( 0, modLibrary.length() - libExt.length() - 1 );
480 libExt = QString( "dll" );
481 if ( SUIT_Tools::extension( modLibrary ).lower() == libExt )
482 modLibrary = modLibrary.mid( 0, modLibrary.length() - libExt.length() - 1 );
484 if ( modLibrary.startsWith( "lib" ) )
485 modLibrary = modLibrary.mid( 3 );
489 modLibrary = modName;
493 inf.title = modTitle;
494 inf.internal = modLibrary;
495 myInfoList.append( inf );
498 if ( myInfoList.isEmpty() ) {
499 if ( desktop() && desktop()->isShown() )
500 SUIT_MessageBox::warn1( desktop(), tr( "Warning" ), tr( "Modules list is empty" ), tr( "&OK" ) );
502 qWarning( tr( "Modules list is empty" ).latin1() );
506 /*!Add common items for popup menu ( if they are exist )
507 *\param type - type of popup menu
508 *\param thePopup - popup menu
509 *\param title - title of popup menu
511 void CAM_Application::contextMenuPopup( const QString& type, QPopupMenu* thePopup, QString& title )
513 // to do : add common items for popup menu ( if they are exist )
514 if ( activeModule() )
515 activeModule()->contextMenuPopup( type, thePopup, title );
518 /*!Create empty study.*/
519 void CAM_Application::createEmptyStudy()
521 /*SUIT_Study* study = */activeStudy();
522 STD_Application::createEmptyStudy();