Salome HOME
Synchronize adm files
[samples/atomsolv.git] / src / ATOMSOLVGUI / ATOMSOLVGUI.cxx
1 // Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
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, or (at your option) any later version.
7 //
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.
12 //
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
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include "ATOMSOLVGUI.h"
21 #include "ATOMSOLVGUI_DataModel.h"
22 #include "ATOMSOLVGUI_Displayer.h"
23 #include "ATOMSOLVGUI_Selection.h"
24 #include "ATOMSOLVGUI_TransparencyDlg.h"
25
26 #include <ATOMSOLV_version.h>
27
28 #include <SUIT_MessageBox.h>
29 #include <SUIT_ResourceMgr.h>
30 #include <SUIT_Session.h>
31 #include <SUIT_Desktop.h>
32 #include <SUIT_ViewManager.h>
33
34 #include <QtxPopupMgr.h>
35
36 #include <SalomeApp_Application.h>
37 #include <SalomeApp_Study.h>
38
39 #include <LightApp_DataOwner.h>
40 #include <LightApp_SelectionMgr.h>
41 #include <LightApp_Preferences.h>
42
43 #include <SVTK_ViewModel.h>
44 #include <SVTK_ViewWindow.h>
45 #include <SALOME_Actor.h>
46
47 #include <SALOME_LifeCycleCORBA.hxx>
48
49 // QT includes
50 #include <qinputdialog.h>
51 #include <qaction.h>
52 #include <qcolordialog.h>
53 #include <qstringlist.h>
54
55 // VTK includes
56 #include <vtkActorCollection.h>
57 #include <vtkRenderer.h>
58
59 using namespace std;
60
61 ATOMSOLV_ORB::ATOMSOLV_Gen_var ATOMSOLVGUI::myEngine = ATOMSOLV_ORB::ATOMSOLV_Gen::_nil();
62
63 // Constructor
64 ATOMSOLVGUI::ATOMSOLVGUI() :
65   SalomeApp_Module( "ATOMSOLV" )
66 {
67 }
68
69 // Initialize a reference to the module's engine
70 void ATOMSOLVGUI::InitATOMSOLVGen( SalomeApp_Application* app )
71 {
72   if ( !app )
73     myEngine = ATOMSOLV_ORB::ATOMSOLV_Gen::_nil();
74   else {
75     Engines::EngineComponent_var comp = app->lcc()->FindOrLoad_Component( "FactoryServer", "ATOMSOLV" );
76     ATOMSOLV_ORB::ATOMSOLV_Gen_ptr atomGen = ATOMSOLV_ORB::ATOMSOLV_Gen::_narrow(comp);
77     ASSERT( !CORBA::is_nil( atomGen ) );
78     myEngine = atomGen;
79   }
80 }
81
82 // Gets an reference to the module's engine
83 ATOMSOLV_ORB::ATOMSOLV_Gen_var ATOMSOLVGUI::GetATOMSOLVGen()
84 {
85   if ( CORBA::is_nil( myEngine ) ) {
86     SUIT_Application* suitApp = SUIT_Session::session()->activeApplication();
87     SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( suitApp );
88     InitATOMSOLVGen( app );
89   }
90   return myEngine;
91 }
92
93 // Module's initialization
94 void ATOMSOLVGUI::initialize( CAM_Application* app )
95 {
96   SalomeApp_Module::initialize( app );
97
98   InitATOMSOLVGen( dynamic_cast<SalomeApp_Application*>( app ) );
99
100   SUIT_Desktop* aParent = app->desktop();
101   SUIT_ResourceMgr* aResourceMgr = app->resourceMgr();
102
103   // create actions
104   QPixmap aPixmap = aResourceMgr->loadPixmap( "ATOMSOLV",tr( "ICON_IMPORT_DATA" ) );
105   createAction( RetrieveData, tr( "TLT_RETRIEVE_DATA" ), QIcon( aPixmap ), tr( "MEN_RETRIEVE_DATA" ),
106                 tr( "STS_RETRIEVE_DATA" ), 0, aParent, false, this, SLOT( OnRetrieveData() ) );
107   aPixmap = aResourceMgr->loadPixmap( "ATOMSOLV",tr( "ICON_PROCESS_DATA" ) );
108   createAction( ProcessData, tr( "TLT_PROCESS_DATA" ), QIcon( aPixmap ), tr( "MEN_PROCESS_DATA" ),
109                 tr( "STS_PROCESS_DATA" ), 0, aParent, false, this, SLOT( OnProcessData() ) );
110
111   // create menus
112   int aMenuId = createMenu( tr( "MEN_ATOMSOLV" ), -1, -1, 30 );
113   createMenu( RetrieveData, aMenuId, 10 );
114   createMenu( ProcessData, aMenuId, 10 );
115
116   // create toolbars
117   int aToolId = createTool ( tr( "TOOL_ATOMSOLV" ) );
118   createTool( RetrieveData, aToolId );
119   createTool( ProcessData, aToolId );
120
121   // custom actions handled by displayer (display, erase, display mode, etc.)
122   aPixmap = aResourceMgr->loadPixmap( "ATOMSOLV",tr( "ICON_DISPLAY" ) );
123   createAction( Display, tr( "TLT_DISPLAY" ), QIcon( aPixmap ), tr( "MEN_DISPLAY" ),
124                 tr( "STS_DISPLAY" ), 0, aParent, false, this, SLOT( OnDisplayerCommand() ) );
125   aPixmap = aResourceMgr->loadPixmap( "ATOMSOLV",tr( "ICON_ERASE" ) );
126   createAction( Erase, tr( "TLT_ERASE" ), QIcon( aPixmap ), tr( "MEN_ERASE" ),
127                 tr( "STS_ERASE" ), 0, aParent, false, this, SLOT( OnDisplayerCommand() ) );
128   createAction( Shading, tr( "TLT_SHADING" ), QIcon(), tr( "MEN_SHADING" ),
129                 tr( "STS_SHADING" ), 0, aParent, true, this, SLOT( OnDisplayerCommand() ) );
130   createAction( Wireframe, tr( "TLT_WIREFRAME" ), QIcon(), tr( "MEN_WIREFRAME" ),
131                 tr( "STS_WIREFRAME" ), 0, aParent, true, this, SLOT( OnDisplayerCommand() ) );
132   createAction( PointsMode, tr( "TLT_POINTSMODE" ), QIcon(), tr( "MEN_POINTSMODE" ),
133                 tr( "STS_POINTSMODE" ), 0, aParent, true, this, SLOT( OnDisplayerCommand() ) );
134   createAction( Color, tr( "TLT_COLOR" ), QIcon(), tr( "MEN_COLOR" ),
135                 tr( "STS_COLOR" ), 0, aParent, false, this, SLOT( OnDisplayerCommand() ) );
136   createAction( Transparency, tr( "TLT_TRANSPARENCY" ), QIcon(), tr( "MEN_TRANSPARENCY" ),
137                 tr( "STS_TRANSPARENCY" ), 0, aParent, false, this, SLOT( OnDisplayerCommand() ) );
138
139   QtxPopupMgr* mgr = popupMgr();
140   mgr->insert( action( Display ), -1, 0 );
141   mgr->insert( action( Erase ), -1, 0 );
142   int dispmodeId = mgr->insert(  tr( "MEN_DISPLAY_MODE" ), -1, -1 ); // display mode menu
143   mgr->insert( action(  PointsMode ), dispmodeId, -1 );
144   mgr->insert( action(  Wireframe ), dispmodeId, -1 );
145   mgr->insert( action(  Shading ), dispmodeId, -1 );
146   mgr->insert( action( Color ), -1, 0 );
147   mgr->insert( action( Transparency ), -1, 0 );
148
149   mgr->setRule( action( Display ), "true in $canBeDisplayed and activeModule='ATOMSOLV' and !isVisible" );
150   mgr->setRule( action( Erase ), "true in $canBeDisplayed and activeModule='ATOMSOLV' and isVisible" );
151   mgr->setRule( action( PointsMode ), "client='VTKViewer' and selcount>0 and isVisible" );
152   mgr->setRule( action( Wireframe ), "client='VTKViewer' and selcount>0 and isVisible" );
153   mgr->setRule( action( Shading ), "client='VTKViewer' and selcount>0 and isVisible" );
154   mgr->setRule( action( Color ), "client='VTKViewer' and selcount>0 and isVisible" );
155   mgr->setRule( action( Transparency ), "client='VTKViewer' and selcount>0 and isVisible" );
156
157   mgr->setRule( action( PointsMode ), "$displaymode={'Points'}", QtxPopupMgr::ToggleRule );
158   mgr->setRule( action( Wireframe ), "$displaymode={'Wireframe'}", QtxPopupMgr::ToggleRule );
159   mgr->setRule( action( Shading ), "$displaymode={'Surface'}", QtxPopupMgr::ToggleRule );
160 }
161
162 // Module's engine IOR
163 QString ATOMSOLVGUI::engineIOR() const
164 {
165   CORBA::String_var anIOR = getApp()->orb()->object_to_string( GetATOMSOLVGen() );
166   return QString( anIOR.in() );
167 }
168
169 // Module's activation
170 bool ATOMSOLVGUI::activateModule( SUIT_Study* theStudy )
171 {
172   bool bOk = SalomeApp_Module::activateModule( theStudy );
173
174   setMenuShown( true );
175   setToolShown( true );
176
177   return bOk;
178 }
179
180 // Module's deactivation
181 bool ATOMSOLVGUI::deactivateModule( SUIT_Study* theStudy )
182 {
183   setMenuShown( false );
184   setToolShown( false );
185
186   return SalomeApp_Module::deactivateModule( theStudy );
187 }
188
189 // Study closed callback
190 void ATOMSOLVGUI::studyClosed( SUIT_Study* theStudy )
191 {
192   if ( theStudy ) {
193     ATOMSOLV_ORB::ATOMSOLV_Gen_var engine = GetATOMSOLVGen();
194     ATOMSOLV_ORB::TMoleculeList lst;
195     lst.length( 0 );
196     engine->setData( theStudy->id(), lst );
197   }
198
199   SalomeApp_Module::studyClosed( theStudy );
200 }
201
202 // Default windows
203 void ATOMSOLVGUI::windows( QMap<int, int>& theMap ) const
204 {
205   theMap.insert( SalomeApp_Application::WT_ObjectBrowser, Qt::LeftDockWidgetArea );
206   theMap.insert( SalomeApp_Application::WT_PyConsole,     Qt::BottomDockWidgetArea );
207 }
208
209 // Default view managers
210 void ATOMSOLVGUI::viewManagers( QStringList& theViewMgrs ) const
211 {
212   theViewMgrs.append( SVTK_Viewer::Type() );
213 }
214
215 // Create custom data model
216 CAM_DataModel* ATOMSOLVGUI::createDataModel()
217 {
218   return new ATOMSOLVGUI_DataModel( this );
219 }
220
221 // Create custom selection object
222 LightApp_Selection* ATOMSOLVGUI::createSelection() const
223 {
224   return new ATOMSOLVGUI_Selection();
225 }
226
227 /*! Returns list of entities of selected objects. */
228 void ATOMSOLVGUI::selected( QStringList& entries, const bool multiple )
229 {
230   LightApp_SelectionMgr* mgr = getApp()->selectionMgr();
231   if( !mgr )
232     return;
233
234   SUIT_DataOwnerPtrList anOwnersList;
235   mgr->selected( anOwnersList );
236
237   for ( int i = 0; i < anOwnersList.size(); i++ )
238   {
239     const LightApp_DataOwner* owner = dynamic_cast<const LightApp_DataOwner*>( anOwnersList[ i ].get() );
240     QStringList es = owner->entry().split( "_" );
241     if ( es.count() > 1 && es[ 0 ] == "ATOMSOLVGUI" && es[ 1 ] != "root" )
242     {
243       if ( !entries.contains( owner->entry() ) )
244         entries.append( owner->entry() );
245       if( !multiple )
246         break;
247     }
248   }
249 }
250
251 // Action slot
252 void ATOMSOLVGUI::OnRetrieveData()
253 {
254   ATOMSOLV_ORB::ATOMSOLV_Gen_var engine = GetATOMSOLVGen();
255   SalomeApp_Application* app = getApp();
256   if ( !CORBA::is_nil( engine ) && app ) {
257     Engines::EngineComponent_var comp = app->lcc()->FindOrLoad_Component( "FactoryServerPy","ATOMGEN" );
258     ATOMGEN_ORB::ATOMGEN_Gen_var atomGen = ATOMGEN_ORB::ATOMGEN_Gen::_narrow( comp );
259     SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*>( app->activeStudy() );
260     if ( !CORBA::is_nil( atomGen ) && appStudy ) {
261       const int studyID = appStudy->id();
262       // in case current study is not loaded by ATOMGEN component - call Load on it
263       if ( _PTR( Study ) studyDS = appStudy->studyDS() ) {
264         if ( _PTR( SComponent ) atomGenSComp = studyDS->FindComponent( "ATOMGEN" ) ) {
265           _PTR( StudyBuilder ) builder = studyDS->NewBuilder();
266           std::string atomGenIOR = app->orb()->object_to_string( atomGen );
267           builder->LoadWith( atomGenSComp, atomGenIOR );
268         }
269       }
270
271       // retrieve data from ATOMGEN
272       ATOMGEN_ORB::MoleculeList_var inData = atomGen->getData( studyID );
273
274       // "convert" Molecules to TMolecules, set default temperature of '0'
275       const int n = inData->length();
276       ATOMSOLV_ORB::TMoleculeList_var outData = new ATOMSOLV_ORB::TMoleculeList();
277       outData->length( n );
278       for ( int i = 0; i < n; i++ ) {
279         ATOMSOLV_ORB::TMolecule_var tmol = new ATOMSOLV_ORB::TMolecule();
280         tmol->molecule = ATOMGEN_ORB::Molecule::_duplicate( inData[i] );
281         tmol->temperature = 0;
282         outData[ i ] = tmol;
283       }
284
285       engine->setData( studyID, outData );
286
287       app->updateObjectBrowser();
288     }
289   }
290 }
291
292 // Action slot
293 void ATOMSOLVGUI::OnProcessData()
294 {
295   ATOMSOLV_ORB::ATOMSOLV_Gen_var engine = GetATOMSOLVGen();
296   SalomeApp_Application* app = getApp();
297   if ( !CORBA::is_nil( engine ) && app ) {
298     if ( const int studyID = app->activeStudy()->id() > 0 ) {
299       // call processData on engine
300       engine->processData( studyID );
301       // update data objects in object browser
302       updateObjBrowser();
303       // redisplay atoms that are already displayed (as their temperature changed..)
304       ViewManagerList vmans;
305       getApp()->viewManagers( SVTK_Viewer::Type(), vmans );
306       for ( QList<SUIT_ViewManager*>::iterator it = vmans.begin(); it != vmans.end(); ++it ) {
307         QVector<SUIT_ViewWindow*> views = (*it)->getViews();
308         for ( int i = 0; i < views.size(); i++ ) {
309           if ( SVTK_ViewWindow* svtkView = dynamic_cast<SVTK_ViewWindow*>( views[ i ] ) ) {
310             vtkActorCollection* actors = svtkView->getRenderer()->GetActors();
311             actors->InitTraversal();
312             while ( vtkActor* actor = actors->GetNextActor() )
313               if ( SALOME_Actor* salomeActor = SALOME_Actor::SafeDownCast( actor ) )
314                 if ( salomeActor->hasIO() ) {
315                   //                  printf( " -- must redisplay actor salomeActor: %s\n", salomeActor->getIO()->getEntry() );
316                   ATOMSOLVGUI_Displayer().updateActor( salomeActor );
317                 }
318           }
319         }
320       }
321     }
322   }
323 }
324
325 // Action slot
326 void ATOMSOLVGUI::OnDisplayerCommand()
327 {
328   const QObject* obj = sender();
329   if ( obj && obj->inherits( "QAction" ) ) {
330     const int id = actionId ( (QAction*)obj );
331     switch ( id ) {
332     case Display : {
333       QStringList entries;
334       selected ( entries, true );
335       ATOMSOLVGUI_Displayer d;
336       for ( QStringList::const_iterator it = entries.begin(), last = entries.end(); it != last; it++ )
337         d.Display( it->toLatin1(), /*updateviewer=*/false, 0 );
338       d.UpdateViewer();
339     } break;
340     case Erase   : {
341       QStringList entries;
342       selected ( entries, true );
343       ATOMSOLVGUI_Displayer d;
344       for ( QStringList::const_iterator it = entries.begin(), last = entries.end(); it != last; it++ )
345         d.Erase( *it, /*forced=*/true, /*updateViewer=*/false, 0 );
346       d.UpdateViewer();
347     } break;
348     case Shading   : {
349       QStringList entries;
350       selected ( entries, true );
351       ATOMSOLVGUI_Displayer().setDisplayMode( entries, "Surface" );
352     } break;
353     case Wireframe   : {
354       QStringList entries;
355       selected ( entries, true );
356       ATOMSOLVGUI_Displayer().setDisplayMode( entries, "Wireframe" );
357     } break;
358     case PointsMode   : {
359       QStringList entries;
360       selected ( entries, true );
361       ATOMSOLVGUI_Displayer().setDisplayMode( entries, "Points" );
362     } break;
363     case Color   : {
364       QStringList entries;
365       selected ( entries, true );
366       QColor initialColor( "white" );
367       if ( entries.count() == 1 )
368         initialColor = ATOMSOLVGUI_Displayer().getColor( entries[ 0 ] );
369       QColor color = QColorDialog::getColor( initialColor, getApp()->desktop() );
370       if ( color.isValid() )
371         ATOMSOLVGUI_Displayer().setColor( entries, color );
372     } break;
373     case Transparency   : {
374       QStringList entries;
375       selected ( entries, true );
376       ATOMSOLVGUI_TransparencyDlg( getApp()->desktop(), entries ).exec();
377     } break;
378     default: printf( "ERROR: Action with ID = %d was not found in ATOMSOLVGUI\n", id ); break;
379     }
380   }
381 }
382
383 // returns a custom displayer object
384 LightApp_Displayer* ATOMSOLVGUI::displayer()
385 {
386   return new ATOMSOLVGUI_Displayer();
387 }
388
389 // create preferences for ATOMSOLV component
390 void ATOMSOLVGUI::createPreferences()
391 {
392   int tabId = addPreference( tr( "ATOMSOLV_PREFERENCES" ) );
393   int groupId = addPreference( tr( "PRESENTATION_PREF_GROUP" ), tabId );
394
395   setPreferenceProperty( groupId, "columns", 1 );
396
397   // Representation mode preference
398   int dispModeId = addPreference( tr( "DISPLAY_MODE_PREF" ), groupId,
399                                   LightApp_Preferences::Selector, "ATOMSOLV", "Representation" );
400   QList<QVariant> intDispModes;
401   QStringList strDispModes;
402   intDispModes.append( 0 ); strDispModes.append( tr( "MEN_POINTSMODE" ) );
403   intDispModes.append( 1 ); strDispModes.append( tr( "MEN_WIREFRAME" ) );
404   intDispModes.append( 2 ); strDispModes.append( tr( "MEN_SHADING" ) );
405
406   setPreferenceProperty( dispModeId, "strings", strDispModes );
407   setPreferenceProperty( dispModeId, "indexes", intDispModes );
408
409   // Radius preference
410   int radisusId = addPreference( tr( "RADIUS_PREF" ), groupId,
411                                  LightApp_Preferences::DblSpin, "ATOMSOLV", "Radius" );
412   setPreferenceProperty( radisusId, "min", .001 );
413   setPreferenceProperty( radisusId, "max", 1000 );
414   setPreferenceProperty( radisusId, "precision", 3 );
415 }
416
417 // preferences of changed: update the corresponding values
418 void ATOMSOLVGUI::preferencesChanged( const QString& group, const QString& param )
419 {
420   if ( group == "ATOMSOLV" && param == "Representation" )
421     ATOMSOLVGUI_Displayer::setDefaultRepresentation( getApp()->resourceMgr()->integerValue( group, param ) );
422   else if ( group == "ATOMSOLV" && param == "Radius" )
423     ATOMSOLVGUI_Displayer::setDefaultRadius( getApp()->resourceMgr()->doubleValue( group, param ) );
424 }
425
426
427 // Export the module
428 extern "C" {
429   ATOMSOLVGUI_EXPORT
430   CAM_Module* createModule()
431   {
432     return new ATOMSOLVGUI();
433   }
434   ATOMSOLVGUI_EXPORT
435   char* getModuleVersion() 
436   {
437     return (char*)ATOMSOLV_VERSION_STR;
438   }
439 }