]> SALOME platform Git repositories - modules/gui.git/blob - src/CAM/CAM_Application.cxx
Salome HOME
5f9696d462de0e9c1ac055cc3197dce2d345eb5e
[modules/gui.git] / src / CAM / CAM_Application.cxx
1 #include "CAM_Application.h"
2
3 #include "CAM_Study.h"
4 #include "CAM_Module.h"
5
6 #include <SUIT_Tools.h>
7 #include <SUIT_Session.h>
8 #include <SUIT_MessageBox.h>
9
10 #include <qfile.h> 
11 #include <qfileinfo.h>
12 #include <qtextstream.h>
13 #include <qlabel.h>
14 #include <qfont.h>
15
16 #ifdef WIN32
17 #include <windows.h>
18 #else
19 #include <dlfcn.h>
20 #endif
21
22 extern "C" CAM_EXPORT SUIT_Application* createApplication()
23 {
24   return new CAM_Application();
25 }
26
27 CAM_Application::CAM_Application( const bool autoLoad )
28 : STD_Application(),
29 myModule( 0 ),
30 myAutoLoad( autoLoad )
31 {
32   readModuleList();
33 }
34
35 CAM_Application::~CAM_Application()
36 {
37 }
38
39 void CAM_Application::start()
40 {
41   if ( myAutoLoad )
42     loadModules();
43
44   STD_Application::start();
45 }
46
47 CAM_Module* CAM_Application::activeModule() const
48 {
49   return myModule;
50 }
51
52 CAM_Module* CAM_Application::module(  const QString& modName ) const
53 {
54   CAM_Module* mod = 0;
55   for ( ModuleListIterator it( myModules ); it.current() && !mod; ++it )
56     if ( it.current()->moduleName() == modName )
57       mod = it.current();
58   return mod;
59 }
60
61 CAM_Application::ModuleListIterator CAM_Application::modules() const
62 {
63   return ModuleListIterator( myModules );
64 }
65
66 void CAM_Application::modules( CAM_Application::ModuleList& out ) const
67 {
68   out.setAutoDelete( false );
69   out.clear();
70
71   for ( ModuleListIterator it( myModules ); it.current(); ++it )
72     out.append( it.current() );
73 }
74
75 void CAM_Application::modules( QStringList& lst, const bool loaded ) const
76 {
77   lst.clear();
78
79   if ( loaded )
80     for ( ModuleListIterator it( myModules ); it.current(); ++it )
81       lst.append( it.current()->moduleName() );
82   else
83     for ( ModuleInfoList::const_iterator it = myInfoList.begin(); it != myInfoList.end(); ++it )
84       lst.append( (*it).title );
85 }
86
87 void CAM_Application::addModule( CAM_Module* mod )
88 {
89   if ( !mod || myModules.contains( mod ) )
90     return;
91
92   mod->initialize( this );
93
94   QMap<CAM_Module*, int> map;
95
96   ModuleList newList;
97   for ( ModuleInfoList::const_iterator it = myInfoList.begin(); it != myInfoList.end(); ++it )
98   {
99     if ( (*it).title == mod->moduleName() )
100       newList.append( mod );
101     else
102     {
103       CAM_Module* curMod = module( (*it).title );
104       if ( curMod )
105         newList.append( curMod );
106     }
107     if ( !newList.isEmpty() )
108       map.insert( newList.getLast(), 0 );
109   }
110
111   for ( ModuleListIterator itr( myModules ); itr.current(); ++itr )
112   {
113     if ( !map.contains( itr.current() ) )
114       newList.append( itr.current() );
115   }
116
117   if ( !map.contains( mod ) )
118       newList.append( mod );
119
120   myModules = newList;
121
122   moduleAdded( mod );
123 }
124
125 void CAM_Application::loadModules()
126 {
127   for ( ModuleInfoList::const_iterator it = myInfoList.begin(); it != myInfoList.end(); ++it )
128   {
129     CAM_Module* mod = loadModule( (*it).title );
130     if ( mod )
131       addModule( mod );
132     else
133       SUIT_MessageBox::error1( desktop(), tr( "Loading modules" ),
134                                tr( "Can not load module %1" ).arg( (*it).title ), tr( "Ok" ) );
135   }
136 }
137
138 CAM_Module* CAM_Application::loadModule( const QString& modName )
139 {
140   if ( myInfoList.isEmpty() )
141   {
142     qWarning( tr( "Modules configuration is not defined." ) );
143     return 0;
144   }
145
146   QString libName = moduleLibrary( modName );
147   if ( libName.isEmpty() )
148   {
149     qWarning( tr( "Information about module \"%1\" doesn't exist." ).arg( modName ) );
150     return 0;
151   }
152
153   QString err;
154   GET_MODULE_FUNC crtInst = 0;
155
156 #ifdef WIN32
157   HINSTANCE modLib = ::LoadLibrary( libName ); 
158   if ( !modLib )
159   {
160     LPVOID lpMsgBuf;
161     ::FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
162                      FORMAT_MESSAGE_IGNORE_INSERTS, 0, ::GetLastError(), 0, (LPTSTR)&lpMsgBuf, 0, 0 );
163     err = QString( "Failed to load  %1. %2" ).arg( libName ).arg( (LPTSTR)lpMsgBuf );
164     ::LocalFree( lpMsgBuf );
165   }
166   else
167   {
168     crtInst = (GET_MODULE_FUNC)::GetProcAddress( modLib, GET_MODULE_NAME );
169     if ( !crtInst )
170     {
171       LPVOID lpMsgBuf;
172       ::FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
173                        FORMAT_MESSAGE_IGNORE_INSERTS, 0, ::GetLastError(), 0, (LPTSTR)&lpMsgBuf, 0, 0 );
174     err = QString( "Failed to find  %1 function. %2" ).arg( GET_MODULE_NAME ).arg( (LPTSTR)lpMsgBuf );
175     ::LocalFree( lpMsgBuf );
176     }
177   }
178 #else
179   void* modLib = dlopen( (char*)libName.latin1(), RTLD_LAZY );
180   if ( !modLib )
181     err = QString( "Can not load library %1. %2" ).arg( libName ).arg( dlerror() );
182   else
183   {
184     crtInst = (GET_MODULE_FUNC)dlsym( modLib, GET_MODULE_NAME );
185     if ( !crtInst )
186       err = QString( "Failed to find function %1. %2" ).arg( GET_MODULE_NAME ).arg( dlerror() );
187   }
188 #endif
189
190   CAM_Module* module = crtInst ? crtInst() : 0;
191   if ( module )
192   {
193     module->setModuleName( modName );
194     module->setName( moduleName( modName ) );
195   }
196
197   if ( !err.isEmpty() )
198     SUIT_MessageBox::warn1( desktop(), tr( "Error" ), err, tr( "Ok" ) );
199
200   return module;
201 }
202
203 bool CAM_Application::activateModule( const QString& modName )
204 {
205   if ( !modName.isEmpty() && !activeStudy() )
206     return false;
207
208   bool res = false;
209   if ( !modName.isEmpty() )
210   {
211     CAM_Module* mod = module( modName );
212     if ( !mod && !moduleLibrary( modName ).isEmpty() )
213     {
214       mod = loadModule( modName );
215       addModule( mod );
216     }
217
218     if ( mod )
219       res = activateModule( mod );
220   }
221   else
222     res = activateModule( 0 );
223
224   return res;
225 }
226
227 bool CAM_Application::activateModule( CAM_Module* mod )
228 {
229   if ( mod && !activeStudy() )
230     return false;
231
232   if ( myModule == mod )
233     return true;
234
235   if ( myModule )
236     myModule->deactivateModule( activeStudy() );
237
238   myModule = mod;
239
240   if ( myModule ){
241     // Connect the module to the active study
242     CAM_Study* camStudy = dynamic_cast<CAM_Study*>( activeStudy() );
243     if ( camStudy ){
244       CAM_DataModel* prev = 0;
245       for ( ModuleListIterator it( myModules ); it.current(); ++it ) {
246         CAM_DataModel* dm = it.current()->dataModel();
247         if ( it.current() == myModule && !camStudy->containsDataModel( dm ) ){
248           if ( prev )
249             camStudy->insertDataModel( it.current()->dataModel(), prev );
250           else
251             camStudy->insertDataModel( it.current()->dataModel(), 0 );
252         }
253         prev = dm;
254       }
255     }
256     myModule->activateModule( activeStudy() );
257   }
258
259   updateCommandsStatus();
260
261   return true;
262 }
263
264 SUIT_Study* CAM_Application::createNewStudy() 
265
266   return new CAM_Study( this );
267 }
268
269 void CAM_Application::updateCommandsStatus()
270 {
271   STD_Application::updateCommandsStatus();
272
273   if ( activeModule() )
274     activeModule()->updateCommandsStatus();
275 }
276
277 void CAM_Application::beforeCloseDoc( SUIT_Study* theDoc )
278 {
279   for ( ModuleListIterator it( myModules ); it.current(); ++it )
280     it.current()->studyClosed( theDoc );
281 }
282
283 void CAM_Application::setActiveStudy( SUIT_Study* study )
284 {
285   STD_Application::setActiveStudy( study );
286 }
287
288 void CAM_Application::moduleAdded( CAM_Module* mod )
289 {
290 //  CAM_Study* study = dynamic_cast<CAM_Study*>( activeStudy() );
291 //  if ( !study )
292 //    return;
293
294 //  study->insertDataModel( mod->dataModel() );
295 }
296
297 QString CAM_Application::moduleName( const QString& title ) const
298 {
299   QString res;
300   for ( ModuleInfoList::const_iterator it = myInfoList.begin(); it != myInfoList.end() && res.isEmpty(); ++it )
301   {
302     if ( (*it).title == title )
303       res = (*it).name;
304   }
305   return res;
306 }
307
308 QString CAM_Application::moduleTitle( const QString& name ) const
309 {
310   QString res;
311   for ( ModuleInfoList::const_iterator it = myInfoList.begin(); it != myInfoList.end() && res.isEmpty(); ++it )
312   {
313     if ( (*it).name == name )
314       res = (*it).title;
315   }
316   return res;
317 }
318
319 QString CAM_Application::moduleLibrary( const QString& title, const bool full ) const
320 {
321   QString res;
322   for ( ModuleInfoList::const_iterator it = myInfoList.begin(); it != myInfoList.end() && res.isEmpty(); ++it )
323   {
324     if ( (*it).title == title )
325       res = (*it).internal;
326   }
327   if ( !res.isEmpty() && full )
328     res = SUIT_Tools::library( res );
329   return res;
330 }
331
332 void CAM_Application::readModuleList()
333 {
334   if ( !myInfoList.isEmpty() )
335     return;
336
337   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
338
339   QString modStr = resMgr->stringValue( "launch", "modules", QString::null );
340   QStringList modList = QStringList::split( ",", modStr );
341
342   for ( QStringList::const_iterator it = modList.begin(); it != modList.end(); ++it )
343   {
344     QString modName = (*it).stripWhiteSpace();
345     if ( modName.isEmpty() )
346       continue;
347
348     QString modTitle = resMgr->stringValue( *it, QString( "name" ), QString::null );
349     if ( modTitle.isEmpty() )
350       continue;
351
352     QString modLibrary = resMgr->stringValue( *it, QString( "library" ), QString::null ).stripWhiteSpace();
353     if ( !modLibrary.isEmpty() )
354     {
355       QString libExt;
356       modLibrary = SUIT_Tools::file( modLibrary.stripWhiteSpace() );
357       libExt = QString( "so" );
358       if ( SUIT_Tools::extension( modLibrary ).lower() == libExt )
359         modLibrary = modLibrary.mid( 0, modLibrary.length() - libExt.length() - 1 );
360       libExt = QString( "dll" );
361       if ( SUIT_Tools::extension( modLibrary ).lower() == libExt )
362         modLibrary = modLibrary.mid( 0, modLibrary.length() - libExt.length() - 1 );
363 #ifndef WIN32
364       if ( modLibrary.startsWith( "lib" ) )
365         modLibrary = modLibrary.mid( 3 );
366 #endif
367     }
368     else
369       modLibrary = modName;
370
371     ModuleInfo inf;
372     inf.name = modName;
373     inf.title = modTitle;
374     inf.internal = modLibrary;
375     myInfoList.append( inf );
376   }
377
378   if ( myInfoList.isEmpty() )
379     SUIT_MessageBox::error1( 0, tr( "Error" ), tr( "Can not load modules configuration file " ), tr( "Ok" ) );
380 }
381
382 void CAM_Application::contextMenuPopup( const QString& type, QPopupMenu* thePopup, QString& title )
383 {
384   // to do : add common items for popup menu ( if they are exist )
385   if ( activeModule() ) 
386     activeModule()->contextMenuPopup( type, thePopup, title );
387 }