Salome HOME
Merge 'abn/V8_1_fix' branch into V8_1_BR.
[modules/med.git] / src / MEDCalc / gui / PresentationController.cxx
1 // Copyright (C) 2016  CEA/DEN, EDF R&D
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 "PresentationController.hxx"
21 #include <MEDCalcConstants.hxx>
22 #include "MEDModule.hxx"
23 #include "Basics_Utils.hxx"
24 #include "QtxActionGroup.h"
25 #include "QtxActionToolMgr.h"
26 #include "MEDFactoryClient.hxx"
27 #include "MEDPresentationManager_i.hxx"
28 #include "XmedConsoleDriver.hxx"
29
30 #include "MEDPresentationMeshView.hxx"
31 #include "MEDPresentationScalarMap.hxx"
32 #include "MEDPresentationContour.hxx"
33 #include "MEDPresentationSlices.hxx"
34 #include "MEDPresentationPointSprite.hxx"
35 #include "MEDPresentationVectorField.hxx"
36 #include "MEDPresentationDeflectionShape.hxx"
37
38 #include "MEDWidgetHelperMeshView.hxx"
39 #include "MEDWidgetHelperScalarMap.hxx"
40 #include "MEDWidgetHelperContour.hxx"
41 #include "MEDWidgetHelperSlices.hxx"
42 #include "MEDWidgetHelperPointSprite.hxx"
43 #include "MEDWidgetHelperVectorField.hxx"
44 #include "MEDWidgetHelperDeflectionShape.hxx"
45
46 #include <SalomeApp_Application.h>
47 #include <SalomeApp_Study.h>
48 #include <SalomeApp_DataObject.h>
49
50 #include <SALOME_ListIO.hxx>
51 #include <LightApp_SelectionMgr.h>
52
53 #include <SALOMEDS_SObject.hxx>
54 #include <SALOMEDS_Study.hxx>
55
56 #include <SUIT_Desktop.h>
57 #include <SUIT_Session.h>
58 #include <SUIT_ResourceMgr.h>
59 #include <QMessageBox>
60 #include <sstream>
61
62 #include "MEDFactoryClient.hxx"
63
64 static const int OPTIONS_VIEW_MODE_ID = 943;
65 static const int OPTIONS_VIEW_MODE_REPLACE_ID = 944;
66 static const int OPTIONS_VIEW_MODE_OVERLAP_ID = 945;
67 static const int OPTIONS_VIEW_MODE_NEW_LAYOUT_ID = 946;
68 static const int OPTIONS_VIEW_MODE_SPLIT_VIEW_ID = 947;
69
70 //! The only instance of the MEDPresentationManager
71 MEDCALC::MEDPresentationManager_ptr PresentationController::_presManager;
72
73 PresentationController::PresentationController(MEDModule* salomeModule) :
74         _salomeModule(salomeModule),
75         _consoleDriver(0),
76         _studyEditor(salomeModule->getStudyEditor()),
77         _presHelperMap(),
78         _currentWidgetHelper(0)
79 {
80   STDLOG("Creating a PresentationController");
81
82   _widgetPresentationParameters = new WidgetPresentationParameters();
83
84   QMainWindow* parent = salomeModule->getApp()->desktop();
85   _dockWidget = new QDockWidget(parent);
86   _dockWidget->setVisible(false);
87   _dockWidget->setWindowTitle(tr("TITLE_PRESENTATION_PARAMETERS"));
88   _dockWidget->setObjectName(tr("TITLE_PRESENTATION_PARAMETERS"));
89   _dockWidget->setFeatures(QDockWidget::AllDockWidgetFeatures);
90   _dockWidget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
91   _dockWidget->setWidget(_widgetPresentationParameters);
92   parent->addDockWidget(Qt::LeftDockWidgetArea, _dockWidget);
93   //_dockWidget->show();
94
95   // Retrieve MEDFactory to get MEDPresentationManager (sometimes GUI needs to talk to the engine directly)
96   if ( ! _presManager ) {
97       _presManager = MEDFactoryClient::getFactory()->getPresentationManager();
98   }
99
100   // Connect to the click in the object browser
101   connect(salomeModule, SIGNAL( presentationSelected(int , const QString&, const QString&) ),
102           this, SLOT(onPresentationSelected(int , const QString&, const QString&) )     );
103 }
104
105 PresentationController::~PresentationController()
106 {
107   STDLOG("Deleting the resentationController");
108   // Clean allocated widget helpers:
109   for ( std::map<int, MEDWidgetHelper *>::iterator it = _presHelperMap.begin(); it != _presHelperMap.end(); ++it)
110     delete((*it).second);
111 }
112
113 int
114 PresentationController::getIntParamFromStudyEditor(SALOMEDS::SObject_var obj, const char * name)
115 {
116   if (obj->_is_nil())
117     return -1;
118
119   SALOMEDS::GenericAttribute_var anAttr;
120   SALOMEDS::AttributeParameter_var aParam;
121   if ( obj->FindAttribute(anAttr,"AttributeParameter") ) {
122     aParam = SALOMEDS::AttributeParameter::_narrow(anAttr);
123     if (aParam->IsSet(name, PT_INTEGER))
124       return aParam->GetInt(name);
125   }
126   return -1;
127 }
128
129 std::string
130 PresentationController::_getIconName(const std::string& name)
131 {
132   SUIT_ResourceMgr* mgr = SUIT_Session::session()->resourceMgr();
133   if (!mgr)
134     return name;
135
136   // Read value from preferences and suffix name to select icon theme
137   int theme = mgr->integerValue("MEDCalc", "icons");
138   if (theme == 0) {
139       return name + "_MODERN";
140   } else if (theme == 1) {
141       return name + "_CLASSIC";
142   }
143   return name + "_DEFAULT";
144 }
145
146 void
147 PresentationController::createActions()
148 {
149   STDLOG("Creating PresentationController actions");
150
151   // View Mode
152   int viewModeToolbarId = _salomeModule->createTool("View Mode", "ViewModeToolbar");
153   QtxActionGroup* ag = _salomeModule->createActionGroup(OPTIONS_VIEW_MODE_ID, true);
154   ag->setText("View mode");
155   ag->setUsesDropDown(true);
156   QString label   = tr("LAB_VIEW_MODE_REPLACE");
157   QString tooltip = tr("TIP_VIEW_MODE_REPLACE");
158   QAction* a = _salomeModule->createAction(OPTIONS_VIEW_MODE_REPLACE_ID,label,QIcon(),label,tooltip,0);
159   a->setCheckable(true);
160   a->setChecked(true);
161   ag->add(a);
162
163   label   = tr("LAB_VIEW_MODE_OVERLAP");
164   tooltip = tr("TIP_VIEW_MODE_OVERLAP");
165   a = _salomeModule->createAction(OPTIONS_VIEW_MODE_OVERLAP_ID,label,QIcon(),label,tooltip,0);
166   a->setCheckable(true);
167   ag->add(a);
168
169   label   = tr("LAB_VIEW_MODE_NEW_LAYOUT");
170   tooltip = tr("TIP_VIEW_MODE_NEW_LAYOUT");
171   a = _salomeModule->createAction(OPTIONS_VIEW_MODE_NEW_LAYOUT_ID,label,QIcon(),label,tooltip,0);
172   a->setCheckable(true);
173   ag->add(a);
174
175   label   = tr("LAB_VIEW_MODE_SPLIT_VIEW");
176   tooltip = tr("TIP_VIEW_MODE_SPLIT_VIEW");
177   a = _salomeModule->createAction(OPTIONS_VIEW_MODE_SPLIT_VIEW_ID,label,QIcon(),label,tooltip,0);
178   a->setCheckable(true);
179   ag->add(a);
180
181   _salomeModule->createTool(OPTIONS_VIEW_MODE_ID, viewModeToolbarId);
182
183   // Presentations
184   int presentationToolbarId = _salomeModule->createTool("Presentations", "PresentationToolbar");
185   int presentationMenuId = _salomeModule->createMenu(tr("MENU_PRESENTATIONS"), -1, -1, 10);
186
187   label   = tr("LAB_PRESENTATION_MESH_VIEW");
188   tooltip = tr("TIP_PRESENTATION_MESH_VIEW");
189   QString icon = tr(_getIconName("ICO_PRESENTATION_MESH_VIEW").c_str());
190   int actionId;
191   actionId = _salomeModule->createStandardAction(label,this, SLOT(onVisualizeMeshView()),icon,tooltip);
192   _salomeModule->createTool(actionId, presentationToolbarId);
193   _salomeModule->action(actionId)->setIconVisibleInMenu(true);
194   _salomeModule->createMenu(actionId, presentationMenuId);
195
196   label   = tr("LAB_PRESENTATION_SCALAR_MAP");
197   tooltip = tr("TIP_PRESENTATION_SCALAR_MAP");
198   icon = tr(_getIconName("ICO_PRESENTATION_SCALAR_MAP").c_str());
199   actionId = _salomeModule->createStandardAction(label,this, SLOT(onVisualizeScalarMap()),icon,tooltip);
200   _salomeModule->createTool(actionId, presentationToolbarId);
201   _salomeModule->action(actionId)->setIconVisibleInMenu(true);
202   _salomeModule->createMenu(actionId, presentationMenuId);
203
204   label   = tr("LAB_PRESENTATION_CONTOUR");
205   tooltip = tr("TIP_PRESENTATION_CONTOUR");
206   icon    = tr(_getIconName("ICO_PRESENTATION_CONTOUR").c_str());
207   actionId = _salomeModule->createStandardAction(label,this, SLOT(onVisualizeContour()),icon,tooltip);
208   _salomeModule->createTool(actionId, presentationToolbarId);
209   _salomeModule->action(actionId)->setIconVisibleInMenu(true);
210   _salomeModule->createMenu(actionId, presentationMenuId);
211
212   label   = tr("LAB_PRESENTATION_VECTOR_FIELD");
213   tooltip = tr("TIP_PRESENTATION_VECTOR_FIELD");
214   icon    = tr(_getIconName("ICO_PRESENTATION_VECTOR_FIELD").c_str());
215   actionId = _salomeModule->createStandardAction(label,this, SLOT(onVisualizeVectorField()),icon,tooltip);
216   _salomeModule->createTool(actionId, presentationToolbarId);
217   _salomeModule->action(actionId)->setIconVisibleInMenu(true);
218   _salomeModule->createMenu(actionId, presentationMenuId);
219
220   label   = tr("LAB_PRESENTATION_SLICES");
221   tooltip = tr("TIP_PRESENTATION_SLICES");
222   icon    = tr(_getIconName("ICO_PRESENTATION_SLICES").c_str());
223   actionId = _salomeModule->createStandardAction(label,this, SLOT(onVisualizeSlices()),icon,tooltip);
224   _salomeModule->createTool(actionId, presentationToolbarId);
225   _salomeModule->action(actionId)->setIconVisibleInMenu(true);
226   _salomeModule->createMenu(actionId, presentationMenuId);
227
228   label   = tr("LAB_PRESENTATION_DEFLECTION_SHAPE");
229   tooltip = tr("TIP_PRESENTATION_DEFLECTION_SHAPE");
230   icon    = tr(_getIconName("ICO_PRESENTATION_DEFLECTION_SHAPE").c_str());
231   actionId = _salomeModule->createStandardAction(label,this, SLOT(onVisualizeDeflectionShape()),icon,tooltip);
232   _salomeModule->createTool(actionId, presentationToolbarId);
233   _salomeModule->action(actionId)->setIconVisibleInMenu(true);
234   _salomeModule->createMenu(actionId, presentationMenuId);
235
236   label   = tr("LAB_PRESENTATION_POINT_SPRITE");
237   tooltip = tr("TIP_PRESENTATION_POINT_SPRITE");
238   icon    = tr(_getIconName("ICO_PRESENTATION_POINT_SPRITE").c_str());
239   actionId = _salomeModule->createStandardAction(label,this, SLOT(onVisualizePointSprite()),icon,tooltip);
240   _salomeModule->createTool(actionId, presentationToolbarId);
241   _salomeModule->action(actionId)->setIconVisibleInMenu(true);
242   _salomeModule->createMenu(actionId, presentationMenuId);
243
244   // Separator
245   _salomeModule->createMenu(_salomeModule->separator(), presentationMenuId);
246
247   label   = tr("LAB_DELETE_PRESENTATION");
248   tooltip = tr("TIP_DELETE_PRESENTATION");
249   icon    = tr("ICO_DELETE_PRESENTATION");
250   actionId = _salomeModule->createStandardAction(label,this, SLOT(onDeletePresentation()),icon,tooltip);
251   //  _salomeModule->createTool(actionId, presentationToolbarId);
252   //  _salomeModule->action(actionId)->setIconVisibleInMenu(true);
253   _salomeModule->createMenu(actionId, presentationMenuId);
254
255   // Low level PARAVIS dump
256   label = tr("LAB_PARAVIS_DUMP");
257   tooltip = tr("TIP_PARAVIS_DUMP");
258   actionId = _salomeModule->createStandardAction(label,this,SLOT(onParavisDump()),"");
259   _salomeModule->createMenu(actionId, presentationMenuId);
260
261   //
262   // Actions for popup menu only
263   //
264
265 }
266
267 MEDCALC::ViewModeType
268 PresentationController::getSelectedViewMode() const
269 {
270   if (_salomeModule->action(OPTIONS_VIEW_MODE_REPLACE_ID)->isChecked()) {
271       return MEDCALC::VIEW_MODE_REPLACE;
272   }
273   else if (_salomeModule->action(OPTIONS_VIEW_MODE_OVERLAP_ID)->isChecked()) {
274       return MEDCALC::VIEW_MODE_OVERLAP;
275   }
276   else if (_salomeModule->action(OPTIONS_VIEW_MODE_NEW_LAYOUT_ID)->isChecked()) {
277       return MEDCALC::VIEW_MODE_NEW_LAYOUT;
278   }
279   else if (_salomeModule->action(OPTIONS_VIEW_MODE_SPLIT_VIEW_ID)->isChecked()) {
280       return MEDCALC::VIEW_MODE_SPLIT_VIEW;
281   }
282   // Should not happen
283   STDLOG("Strange!! No matching view mode found - returning VIEW_MODE_REPLACE.");
284   return MEDCALC::VIEW_MODE_REPLACE;
285 }
286
287 MEDCALC::ColorMapType
288 PresentationController::getSelectedColorMap() const
289 {
290   return _widgetPresentationParameters->getColorMap();
291 }
292
293 MEDCALC::ScalarBarRangeType
294 PresentationController::getSelectedScalarBarRange() const
295 {
296   return _widgetPresentationParameters->getScalarBarRange();
297 }
298
299 void
300 PresentationController::visualize(PresentationEvent::EventType eventType)
301 {
302   // We need a _studyEditor updated on the active study
303   _studyEditor->updateActiveStudy();
304
305   // Get the selected objects in the study (SObject)
306   SALOME_StudyEditor::SObjectList* listOfSObject = _studyEditor->getSelectedObjects();
307
308   // For each object, emit a signal to the workspace to request a
309   // visualisation using the tui command (so that the user can see how
310   // to make a view of an object from the tui console).
311   for (int i=0; i<listOfSObject->size(); i++) {
312       SALOMEDS::SObject_var soObj = listOfSObject->at(i);
313       std::string name(_studyEditor->getName(soObj));
314       if (soObj->_is_nil() || name == "MEDCalc")
315         return;
316
317       int fieldId = getIntParamFromStudyEditor(soObj, FIELD_ID);
318       int meshId = getIntParamFromStudyEditor(soObj, MESH_ID);
319       MEDCALC::FieldHandler* fieldHandler = 0;
320       MEDCALC::MeshHandler* meshHandler = 0;
321
322       // is it a mesh?
323       if (meshId >= 0)
324         {
325           if (eventType != PresentationEvent::EVENT_VIEW_OBJECT_MESH_VIEW)
326             continue;
327           meshHandler = MEDFactoryClient::getDataManager()->getMeshHandler(meshId);
328         }
329       else
330         {
331           if (fieldId < 0)  // is it a field serie ?
332             {
333               int fieldSeriesId = getIntParamFromStudyEditor(soObj, FIELD_SERIES_ID);
334               // If fieldId and fieldSeriesId equals -1, then it means that it is not a field
335               // managed by the MED module, and we stop this function process.
336               if ( fieldSeriesId < 0)
337                   continue;
338
339               MEDCALC::FieldHandlerList* fieldHandlerList = MEDFactoryClient::getDataManager()->getFieldListInFieldseries(fieldSeriesId);
340               if (fieldHandlerList->length() < 0)
341                 continue;
342               // For a field series, get the first real field entry:
343               MEDCALC::FieldHandler fieldHandler = (*fieldHandlerList)[0];
344               fieldId = fieldHandler.id;
345             }
346           fieldHandler = MEDFactoryClient::getDataManager()->getFieldHandler(fieldId);
347         }
348
349       if ((!fieldHandler) && (!meshHandler)) {
350           QMessageBox::warning(_salomeModule->getApp()->desktop(),
351                                tr("Operation not allowed"),
352                                tr("No field (or mesh) is defined"));
353           return;
354       }
355
356       PresentationEvent* event = new PresentationEvent();
357       event->eventtype = eventType;
358       event->fieldHandler = fieldHandler;
359       event->meshHandler = meshHandler;
360       emit presentationSignal(event); // --> processPresentationEvent()
361   }
362 }
363
364 void
365 PresentationController::onVisualizeMeshView()
366 {
367   this->visualize(PresentationEvent::EVENT_VIEW_OBJECT_MESH_VIEW);
368 }
369
370 void
371 PresentationController::onVisualizeScalarMap()
372 {
373   this->visualize(PresentationEvent::EVENT_VIEW_OBJECT_SCALAR_MAP);
374 }
375
376 void
377 PresentationController::onVisualizeContour()
378 {
379   this->visualize(PresentationEvent::EVENT_VIEW_OBJECT_CONTOUR);
380 }
381
382 void
383 PresentationController::onVisualizeVectorField()
384 {
385   this->visualize(PresentationEvent::EVENT_VIEW_OBJECT_VECTOR_FIELD);
386 }
387
388 void
389 PresentationController::onVisualizeSlices()
390 {
391   this->visualize(PresentationEvent::EVENT_VIEW_OBJECT_SLICES);
392 }
393
394 void
395 PresentationController::onVisualizeDeflectionShape()
396 {
397   this->visualize(PresentationEvent::EVENT_VIEW_OBJECT_DEFLECTION_SHAPE);
398 }
399
400 void
401 PresentationController::onVisualizePointSprite()
402 {
403   this->visualize(PresentationEvent::EVENT_VIEW_OBJECT_POINT_SPRITE);
404 }
405
406 void
407 PresentationController::onDeletePresentation()
408 {
409   // We need a _studyEditor updated on the active study
410   _studyEditor->updateActiveStudy();
411
412   // Get the selected objects in the study (SObject)
413   SALOME_StudyEditor::SObjectList* listOfSObject = _studyEditor->getSelectedObjects();
414
415   // For each object, emit a signal to the workspace to request pres deletion
416   for (int i=0; i<listOfSObject->size(); i++) {
417       SALOMEDS::SObject_var soPres = listOfSObject->at(i);
418       std::string name(_studyEditor->getName(soPres));
419       if (soPres->_is_nil() || name == "MEDCalc")
420         return;
421       int presId = getIntParamFromStudyEditor(soPres,PRESENTATION_ID);
422       // If fieldId equals -1, then it means that it is not a field
423       // managed by the MED module, and we stop this function process.
424       if ( presId < 0 )
425         continue;
426
427       PresentationEvent* event = new PresentationEvent();
428       event->eventtype = PresentationEvent::EVENT_DELETE_PRESENTATION;
429       event->presentationId = presId;
430       emit presentationSignal(event); // --> processPresentationEvent()
431   }
432 }
433
434 QString
435 PresentationController::getViewModePython() const
436 {
437   MEDCALC::ViewModeType viewMode = getSelectedViewMode();
438   switch(viewMode) {
439     case MEDCALC::VIEW_MODE_REPLACE: return "MEDCALC.VIEW_MODE_REPLACE";
440     case MEDCALC::VIEW_MODE_OVERLAP: return "MEDCALC.VIEW_MODE_OVERLAP";
441     case MEDCALC::VIEW_MODE_NEW_LAYOUT: return "MEDCALC.VIEW_MODE_NEW_LAYOUT";
442     case MEDCALC::VIEW_MODE_SPLIT_VIEW: return "MEDCALC.VIEW_MODE_SPLIT_VIEW";
443   }
444   return QString();
445 }
446
447 QString
448 PresentationController::getColorMapPython() const
449 {
450   MEDCALC::ColorMapType colorMap = getSelectedColorMap();
451   switch(colorMap) {
452     case MEDCALC::COLOR_MAP_BLUE_TO_RED_RAINBOW: return "MEDCALC.COLOR_MAP_BLUE_TO_RED_RAINBOW";
453     case MEDCALC::COLOR_MAP_COOL_TO_WARM: return "MEDCALC.COLOR_MAP_COOL_TO_WARM";
454   }
455   return QString();
456 }
457
458 QString
459 PresentationController::getScalarBarRangePython() const
460 {
461   MEDCALC::ScalarBarRangeType colorMap = getSelectedScalarBarRange();
462   switch(colorMap) {
463     case MEDCALC::SCALAR_BAR_ALL_TIMESTEPS: return "MEDCALC.SCALAR_BAR_ALL_TIMESTEPS";
464     case MEDCALC::SCALAR_BAR_CURRENT_TIMESTEP: return "MEDCALC.SCALAR_BAR_CURRENT_TIMESTEP";
465   }
466   return QString();
467 }
468
469 QString
470 PresentationController::getMeshModePython(const int mode) const
471 {
472   MEDCALC::MeshModeType mod = static_cast<MEDCALC::MeshModeType>(mode);
473   switch(mod) {
474     case MEDCALC::MESH_MODE_WIREFRAME:     return "MEDCALC.MESH_MODE_WIREFRAME";
475     case MEDCALC::MESH_MODE_SURFACE:       return "MEDCALC.MESH_MODE_SURFACE";
476     case MEDCALC::MESH_MODE_SURFACE_EDGES: return "MEDCALC.MESH_MODE_SURFACE_EDGES";
477   }
478   return QString();
479 }
480
481 QString
482 PresentationController::getSliceOrientationPython(const int orientation) const
483 {
484   MEDCALC::SliceOrientationType orient = static_cast<MEDCALC::SliceOrientationType>(orientation);
485   switch(orient) {
486     case MEDCALC::SLICE_NORMAL_TO_X:   return "MEDCALC.SLICE_NORMAL_TO_X";
487     case MEDCALC::SLICE_NORMAL_TO_Y:   return "MEDCALC.SLICE_NORMAL_TO_Y";
488     case MEDCALC::SLICE_NORMAL_TO_Z:   return "MEDCALC.SLICE_NORMAL_TO_Z";
489     case MEDCALC::SLICE_NORMAL_TO_XY:  return "MEDCALC.SLICE_NORMAL_TO_XY";
490     case MEDCALC::SLICE_NORMAL_TO_XZ:  return "MEDCALC.SLICE_NORMAL_TO_XZ";
491     case MEDCALC::SLICE_NORMAL_TO_YZ:  return "MEDCALC.SLICE_NORMAL_TO_YZ";
492     case MEDCALC::SLICE_NORMAL_TO_XYZ: return "MEDCALC.SLICE_NORMAL_TO_XYZ";
493   }
494   return QString();
495 }
496
497 std::string
498 PresentationController::getPresTypeFromWidgetHelper(int presId) const
499 {
500   std::map<int, MEDWidgetHelper *>::const_iterator it =_presHelperMap.find(presId);
501   if (it != _presHelperMap.end())
502     return (*it).second->getPythonTag();
503   return "UNKNOWN";
504 }
505
506 void
507 PresentationController::processPresentationEvent(const PresentationEvent* event) {
508   // --> Send commands to SALOME Python console
509   QString viewMode = getViewModePython();
510   QString colorMap = getColorMapPython();
511   QString scalarBarRange = getScalarBarRangePython();
512   MEDCALC::FieldHandler* fieldHandler = event->fieldHandler;
513   QStringList commands;
514
515   // [ABN] using event mechanism for all this is awkward? TODO: direct implementation in each
516   // dedicated widget helper class?
517
518   if ( event->eventtype == PresentationEvent::EVENT_VIEW_OBJECT_MESH_VIEW ) {
519       // Do we request mesh view from a field or from a mesh only?
520       int meshId = event->meshHandler ? event->meshHandler->id : event->fieldHandler->meshid;
521       commands += QString("presentation_id = medcalc.MakeMeshView(%1, viewMode=%2)").arg(meshId).arg(viewMode);
522       commands += QString("presentation_id");
523     }
524   else if ( event->eventtype == PresentationEvent::EVENT_VIEW_OBJECT_SCALAR_MAP ) {
525       commands += QString("presentation_id = medcalc.MakeScalarMap(accessField(%1), viewMode=%2, scalarBarRange=%3, colorMap=%4)")
526           .arg(fieldHandler->id).arg(viewMode).arg(scalarBarRange).arg(colorMap);
527       commands += QString("presentation_id");
528   }
529   else if ( event->eventtype == PresentationEvent::EVENT_VIEW_OBJECT_CONTOUR ) {
530       commands += QString("presentation_id = medcalc.MakeContour(accessField(%1), viewMode=%2, scalarBarRange=%3, colorMap=%4)")
531             .arg(fieldHandler->id).arg(viewMode).arg(scalarBarRange).arg(colorMap);
532       commands += QString("presentation_id");
533   }
534   else if ( event->eventtype == PresentationEvent::EVENT_VIEW_OBJECT_SLICES ) {
535       commands += QString("presentation_id = medcalc.MakeSlices(accessField(%1), viewMode=%2, scalarBarRange=%3, colorMap=%4)")
536             .arg(fieldHandler->id).arg(viewMode).arg(scalarBarRange).arg(colorMap);
537       commands += QString("presentation_id");
538   }
539   else if ( event->eventtype == PresentationEvent::EVENT_VIEW_OBJECT_VECTOR_FIELD ) {
540       commands += QString("presentation_id = medcalc.MakeVectorField(accessField(%1), viewMode=%2, scalarBarRange=%3, colorMap=%4)")
541           .arg(fieldHandler->id).arg(viewMode).arg(scalarBarRange).arg(colorMap);
542       commands += QString("presentation_id");
543   }
544   else if ( event->eventtype == PresentationEvent::EVENT_VIEW_OBJECT_POINT_SPRITE ) {
545       commands += QString("presentation_id = medcalc.MakePointSprite(accessField(%1), viewMode=%2, scalarBarRange=%3, colorMap=%4)")
546               .arg(fieldHandler->id).arg(viewMode).arg(scalarBarRange).arg(colorMap);
547       commands += QString("presentation_id");
548   }
549     else if ( event->eventtype == PresentationEvent::EVENT_VIEW_OBJECT_DEFLECTION_SHAPE ) {
550       commands += QString("presentation_id = medcalc.MakeDeflectionShape(accessField(%1), viewMode=%2, scalarBarRange=%3, colorMap=%4)")
551           .arg(fieldHandler->id).arg(viewMode).arg(scalarBarRange).arg(colorMap);
552       commands += QString("presentation_id");
553   }
554
555
556   else if ( event->eventtype == PresentationEvent::EVENT_CHANGE_COMPONENT ) {
557       std::string typ = getPresTypeFromWidgetHelper(event->presentationId);
558       commands += QString("params = medcalc.Get%1Parameters(%2)").arg(QString::fromStdString(typ)).arg(event->presentationId);
559       commands += QString("params.displayedComponent = '%1'").arg(QString::fromStdString(event->aString));
560       commands += QString("medcalc.Update%1(%2, params)").arg(QString::fromStdString(typ)).arg(event->presentationId);
561   }
562   else if ( event->eventtype == PresentationEvent::EVENT_CHANGE_COLORMAP ) {
563       std::string typ = getPresTypeFromWidgetHelper(event->presentationId);
564       commands += QString("params = medcalc.Get%1Parameters(%2)").arg(QString::fromStdString(typ)).arg(event->presentationId);
565       commands += QString("params.colorMap = %1").arg(getColorMapPython());
566       commands += QString("medcalc.Update%1(%2, params)").arg(QString::fromStdString(typ)).arg(event->presentationId);
567   }
568   else if ( event->eventtype == PresentationEvent::EVENT_CHANGE_TIME_RANGE ) {
569       std::string typ = getPresTypeFromWidgetHelper(event->presentationId);
570       commands += QString("params = medcalc.Get%1Parameters(%2)").arg(QString::fromStdString(typ)).arg(event->presentationId);
571       commands += QString("params.scalarBarRange = %1").arg(getScalarBarRangePython());
572       commands += QString("medcalc.Update%1(%2, params)").arg(QString::fromStdString(typ)).arg(event->presentationId);
573   }
574   else if ( event->eventtype == PresentationEvent::EVENT_CHANGE_NB_CONTOUR ) {
575       std::string typ = getPresTypeFromWidgetHelper(event->presentationId);
576       commands += QString("params = medcalc.GetContourParameters(%2)").arg(event->presentationId);
577       commands += QString("params.nbContours = %1").arg(event->anInteger);
578       commands += QString("medcalc.UpdateContour(%1, params)").arg(event->presentationId);
579   }
580   else if ( event->eventtype == PresentationEvent::EVENT_CHANGE_MESH_MODE ) {
581       std::string typ = getPresTypeFromWidgetHelper(event->presentationId);
582       commands += QString("params = medcalc.GetMeshViewParameters(%2)").arg(event->presentationId);
583       commands += QString("params.mode = %1").arg(getMeshModePython(event->anInteger));
584       commands += QString("medcalc.UpdateMeshView(%1, params)").arg(event->presentationId);
585   }
586   else if ( event->eventtype == PresentationEvent::EVENT_CHANGE_NB_SLICES ) {
587       std::string typ = getPresTypeFromWidgetHelper(event->presentationId);
588       commands += QString("params = medcalc.GetSlicesParameters(%2)").arg(event->presentationId);
589       commands += QString("params.nbSlices = %1").arg(event->anInteger);
590       commands += QString("medcalc.UpdateSlices(%1, params)").arg(event->presentationId);
591   }
592   else if ( event->eventtype == PresentationEvent::EVENT_CHANGE_SLICE_ORIENTATION ) {
593       std::string typ = getPresTypeFromWidgetHelper(event->presentationId);
594       commands += QString("params = medcalc.GetSlicesParameters(%2)").arg(event->presentationId);
595       commands += QString("params.orientation = %1").arg(getSliceOrientationPython(event->anInteger));
596       commands += QString("medcalc.UpdateSlices(%1, params)").arg(event->presentationId);
597   }
598
599   else if ( event->eventtype == PresentationEvent::EVENT_DELETE_PRESENTATION ) {
600       commands += QString("medcalc.RemovePresentation(%1)").arg(event->presentationId);
601   }
602   else {
603       STDLOG("The event "<<event->eventtype<<" is not implemented yet");
604   }
605   _consoleDriver->exec(commands);
606 }
607
608 MEDWidgetHelper *
609 PresentationController::findOrCreateWidgetHelper(MEDCALC::MEDPresentationManager_ptr presManager,
610                                                  int presId, const std::string& type, const std::string& name )
611 {
612   std::map<int, MEDWidgetHelper *>::const_iterator it =_presHelperMap.find(presId);
613   if (it != _presHelperMap.end())
614     return (*it).second;
615   MEDWidgetHelper * wh = 0;
616   if (type == MEDPresentationMeshView::TYPE_NAME)
617     wh = new MEDWidgetHelperMeshView(this, _presManager, presId, name, _widgetPresentationParameters);
618   else if (type == MEDPresentationScalarMap::TYPE_NAME)
619     wh = new MEDWidgetHelperScalarMap(this, _presManager, presId, name, _widgetPresentationParameters);
620   else if (type == MEDPresentationContour::TYPE_NAME)
621     wh = new MEDWidgetHelperContour(this, _presManager, presId, name, _widgetPresentationParameters);
622   else if (type == MEDPresentationSlices::TYPE_NAME)
623     wh = new MEDWidgetHelperSlices(this, _presManager, presId, name, _widgetPresentationParameters);
624   else if (type == MEDPresentationVectorField::TYPE_NAME)
625     wh = new MEDWidgetHelperVectorField(this, _presManager, presId, name, _widgetPresentationParameters);
626   else if (type == MEDPresentationPointSprite::TYPE_NAME)
627     wh = new MEDWidgetHelperPointSprite(this, _presManager, presId, name, _widgetPresentationParameters);
628   else if (type == MEDPresentationDeflectionShape::TYPE_NAME)
629     wh = new MEDWidgetHelperDeflectionShape(this, _presManager, presId, name, _widgetPresentationParameters);
630   else
631     {
632       const char * msg ="findOrCreateWidgetHelper(): NOT IMPLEMENTED !!!";
633       STDLOG(msg);
634       return wh;
635     }
636   _presHelperMap[presId] = wh;
637   return wh;
638 }
639
640 void
641 PresentationController::onPresentationSelected(int presId, const QString& presType, const QString& presName)
642 {
643   if (presId == -1)
644     {
645       if (_widgetPresentationParameters->isShown())
646         {
647           _widgetPresentationParameters->toggleWidget(false);
648           if(_currentWidgetHelper)
649             _currentWidgetHelper->releaseWidget();
650         }
651     }
652   else
653     {
654       if(_currentWidgetHelper)
655         _currentWidgetHelper->releaseWidget();
656       // Activate corresponding ParaView render view
657       _presManager->activateView(presId);
658       // Update widgets parameters
659       _currentWidgetHelper = findOrCreateWidgetHelper(_presManager, presId, presType.toStdString(), presName.toStdString());
660       _currentWidgetHelper->updateWidget(true);
661     }
662 }
663
664 void
665 PresentationController::onParavisDump()
666 {
667   // We need a _studyEditor updated on the active study
668   _studyEditor->updateActiveStudy();
669
670   // Get the selected objects in the study (SObject)
671   SALOME_StudyEditor::SObjectList* listOfSObject = _studyEditor->getSelectedObjects();
672
673   // For the first object only, request the dump
674   for (int i=0; i<listOfSObject->size(); i++) {
675       SALOMEDS::SObject_var soPres = listOfSObject->at(i);
676       std::string name(_studyEditor->getName(soPres));
677       if (soPres->_is_nil() || name == "MEDCalc")
678         return;
679       int presId = getIntParamFromStudyEditor(soPres,PRESENTATION_ID);
680       // If fieldId equals -1, then it means that it is not a field
681       // managed by the MED module, and we stop this function process.
682       if ( presId < 0 )
683         continue;
684
685       std::string dump(_presManager->getParavisDump(presId));
686       std::cerr << "#====== ParaVis dump (presentation "  << presId << ") =====" << std::endl;
687       std::cerr << dump;
688       std::cerr << "#====== End of ParaVis dump =============== " << std::endl;
689
690       break; // stop at the first one
691   }
692 }
693
694 void
695 PresentationController::updateTreeViewWithNewPresentation(long dataId, long presentationId)
696 {
697   if (presentationId < 0) {
698       std::cerr << "Unknown presentation\n";
699       return;
700   }
701
702   std::string name(_presManager->getPresentationStringProperty(presentationId, MEDPresentation::PROP_NAME.c_str()));
703   std::string type = name;
704   std::string icon = std::string("ICO_") + type;
705   icon = _getIconName(icon);
706   std::string ico = tr(icon.c_str()).toStdString();
707
708   // Append presentation ID to the displayed name in the OB:
709   std::ostringstream oss;
710   name = tr(name.c_str()).toStdString();
711   oss << name << " (" << presentationId << ")";
712
713   SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>(_salomeModule->application()->activeStudy());
714   _PTR(Study) studyDS = study->studyDS();
715
716   // Mesh views are always registered at the mesh level:
717   if (type == MEDPresentationMeshView::TYPE_NAME)
718     {
719       _salomeModule->engine()->registerPresentationMesh(_CAST(Study, studyDS)->GetStudy(), dataId,
720           oss.str().c_str(), type.c_str(),ico.c_str(), presentationId);
721     }
722   else
723     _salomeModule->engine()->registerPresentationField(_CAST(Study, studyDS)->GetStudy(), dataId,
724             oss.str().c_str(), type.c_str(),ico.c_str(), presentationId);
725
726   // update Object browser
727   _salomeModule->getApp()->updateObjectBrowser(true);
728
729   // auto-select new presentation
730   std::string entry = _salomeModule->engine()->getStudyPresentationEntry(_CAST(Study, studyDS)->GetStudy(), presentationId);
731   SALOME_ListIO selectedObjects;
732   LightApp_Study* lightStudy = dynamic_cast<LightApp_Study*>( _salomeModule->application()->activeStudy() );
733   QString component = lightStudy->componentDataType( entry.c_str() );
734   selectedObjects.Append( new SALOME_InteractiveObject( (const char*)entry.c_str(),
735                                                         (const char*)component.toLatin1(),
736                                                         ""/*refobj->Name().c_str()*/ ) );
737   //QStringList selectedObjects;
738   //selectedObjects << QString(entry.c_str());
739   LightApp_SelectionMgr* aSelectionMgr = _salomeModule->getApp()->selectionMgr();
740   aSelectionMgr->setSelectedObjects(selectedObjects, false);
741
742   // emit onPresentationSelected
743   int presId = -1;
744   _salomeModule->itemClickGeneric(name, type, presId);
745   onPresentationSelected(presId, QString::fromStdString(type), QString::fromStdString(name));
746 }
747
748 void
749 PresentationController::updateTreeViewForPresentationRemoval(long presentationId)
750 {
751   if (presentationId < 0) {
752       std::cerr << "Unknown presentation\n";
753       return;
754   }
755
756   SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>(_salomeModule->application()->activeStudy());
757   _PTR(Study) studyDS = study->studyDS();
758
759   _salomeModule->engine()->unregisterPresentation(_CAST(Study, studyDS)->GetStudy(), presentationId);
760
761   // update Object browser
762   _salomeModule->getApp()->updateObjectBrowser(true);
763 }
764
765 void
766 PresentationController::_dealWithReplaceMode()
767 {
768   // Deal with replace mode: presentations with invalid IDs have to be removed:
769   SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>(_salomeModule->application()->activeStudy());
770   _PTR(Study) studyDS = study->studyDS();
771
772   MEDCALC::PresentationsList * lstManager = _presManager->getAllPresentations();
773   MED_ORB::PresentationsList * lstModule = _salomeModule->engine()->getStudyPresentations(_CAST(Study, studyDS)->GetStudy());
774   // The IDs not in the intersection needs deletion:
775   CORBA::Long * last = lstManager->get_buffer() + lstManager->length();
776   for (unsigned i = 0; i < lstModule->length(); i++) {
777     CORBA::Long * ptr = std::find(lstManager->get_buffer(), last, (*lstModule)[i]);
778     if (ptr == last) {
779       STDLOG("Removing pres " << (*lstModule)[i] << " from OB.");
780       // Presentation in module but not in manager anymore: to be deleted from OB:
781       updateTreeViewForPresentationRemoval((*lstModule)[i]);
782     }
783   }
784 }
785
786 void
787 PresentationController::processWorkspaceEvent(const MEDCALC::MedEvent* event)
788 {
789   if ( event->type == MEDCALC::EVENT_ADD_PRESENTATION ) {
790     if (event->dataId == -1) {
791       // A file has been loaded, and we want to create a default presentation (MeshView) for it
792       QString viewMode = getViewModePython();
793       QStringList commands;
794       commands += QString("presentation_id = medcalc.MakeMeshView(medcalc.GetFirstMeshFromDataSource(source_id), viewMode=%1)").arg(viewMode);
795       commands += QString("presentation_id");
796       _consoleDriver->exec(commands);
797     }
798     else {
799       updateTreeViewWithNewPresentation(event->dataId, event->presentationId);
800       _dealWithReplaceMode();
801     }
802   }
803   else if ( event->type == MEDCALC::EVENT_REMOVE_PRESENTATION ) {
804       updateTreeViewForPresentationRemoval(event->presentationId);
805       // Hide parameter widget if necessary:
806       onPresentationSelected(-1, "", "");
807   }
808   else if ( event->type == MEDCALC::EVENT_MODIFY_PRESENTATION ) {
809       // Update parameter widget if shown:
810       if(_currentWidgetHelper)
811         _currentWidgetHelper->updateWidget(false);
812   }
813 }
814
815 void
816 PresentationController::showDockWidgets(bool isVisible)
817 {
818   _dockWidget->setVisible(isVisible);
819 }