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