Salome HOME
Merge remote-tracking branch 'origin/vsr/qtesting'
[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
29 #include <SalomeApp_Application.h>
30 #include <SalomeApp_Study.h>
31 #include <SalomeApp_DataObject.h>
32
33 #include <SALOMEDS_SObject.hxx>
34 #include <SALOMEDS_Study.hxx>
35
36 #include <SUIT_Desktop.h>
37 #include <SUIT_Session.h>
38 #include <SUIT_ResourceMgr.h>
39 #include <QMessageBox>
40 #include <sstream>
41
42 static const int OPTIONS_VIEW_MODE_ID = 943;
43 static const int OPTIONS_VIEW_MODE_REPLACE_ID = 944;
44 static const int OPTIONS_VIEW_MODE_OVERLAP_ID = 945;
45 static const int OPTIONS_VIEW_MODE_NEW_LAYOUT_ID = 946;
46 static const int OPTIONS_VIEW_MODE_SPLIT_VIEW_ID = 947;
47
48 PresentationController::PresentationController(MEDModule* salomeModule) :
49     _salomeModule(salomeModule),
50     _studyEditor(salomeModule->getStudyEditor())
51 {
52   STDLOG("Creating a PresentationController");
53
54   _widgetPresentationParameters = new WidgetPresentationParameters();
55
56   QMainWindow* parent = salomeModule->getApp()->desktop();
57   _dockWidget = new QDockWidget(parent);
58   _dockWidget->setVisible(false);
59   _dockWidget->setWindowTitle(tr("TITLE_PRESENTATION_PARAMETERS"));
60   _dockWidget->setObjectName(tr("TITLE_PRESENTATION_PARAMETERS"));
61   _dockWidget->setFeatures(QDockWidget::AllDockWidgetFeatures);
62   _dockWidget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
63   _dockWidget->setWidget(_widgetPresentationParameters);
64   parent->addDockWidget(Qt::LeftDockWidgetArea, _dockWidget);
65   //_dockWidget->show();
66 }
67
68 PresentationController::~PresentationController()
69 {
70   STDLOG("Deleting the PresentationController");
71 }
72
73 std::string
74 PresentationController::_getIconName(const std::string& name)
75 {
76   SUIT_ResourceMgr* mgr = SUIT_Session::session()->resourceMgr();
77   if (!mgr)
78     return name;
79
80   // Read value from preferences and suffix name to select icon theme
81   int theme = mgr->integerValue("MEDCalc", "icons");
82   if (theme == 0) {
83     return name + "_MODERN";
84   } else if (theme == 1) {
85     return name + "_CLASSIC";
86   }
87   return name + "_DEFAULT";
88 }
89
90 void
91 PresentationController::createActions()
92 {
93   STDLOG("Creating PresentationController actions");
94
95   // View Mode
96   int viewModeToolbarId = _salomeModule->createTool("View Mode", "ViewModeToolbar");
97   QtxActionGroup* ag = _salomeModule->createActionGroup(OPTIONS_VIEW_MODE_ID, true);
98   ag->setText("View mode");
99   ag->setUsesDropDown(true);
100   QString label   = tr("LAB_VIEW_MODE_REPLACE");
101   QString tooltip = tr("TIP_VIEW_MODE_REPLACE");
102   QAction* a = _salomeModule->createAction(OPTIONS_VIEW_MODE_REPLACE_ID,label,QIcon(),label,tooltip,0);
103   a->setCheckable(true);
104   a->setChecked(true);
105   ag->add(a);
106
107   label   = tr("LAB_VIEW_MODE_OVERLAP");
108   tooltip = tr("TIP_VIEW_MODE_OVERLAP");
109   a = _salomeModule->createAction(OPTIONS_VIEW_MODE_OVERLAP_ID,label,QIcon(),label,tooltip,0);
110   a->setCheckable(true);
111   ag->add(a);
112
113   label   = tr("LAB_VIEW_MODE_NEW_LAYOUT");
114   tooltip = tr("TIP_VIEW_MODE_NEW_LAYOUT");
115   a = _salomeModule->createAction(OPTIONS_VIEW_MODE_NEW_LAYOUT_ID,label,QIcon(),label,tooltip,0);
116   a->setCheckable(true);
117   ag->add(a);
118
119   label   = tr("LAB_VIEW_MODE_SPLIT_VIEW");
120   tooltip = tr("TIP_VIEW_MODE_SPLIT_VIEW");
121   a = _salomeModule->createAction(OPTIONS_VIEW_MODE_SPLIT_VIEW_ID,label,QIcon(),label,tooltip,0);
122   a->setCheckable(true);
123   ag->add(a);
124
125   _salomeModule->createTool(OPTIONS_VIEW_MODE_ID, viewModeToolbarId);
126
127   // Presentations
128   int presentationToolbarId = _salomeModule->createTool("Presentations", "PresentationToolbar");
129   int presentationMenuId = _salomeModule->createMenu(tr("MENU_PRESENTATIONS"), -1, 1);
130
131   label   = tr("LAB_PRESENTATION_SCALAR_MAP");
132   tooltip = tr("TIP_PRESENTATION_SCALAR_MAP");
133   QString icon = tr(_getIconName("ICO_PRESENTATION_SCALAR_MAP").c_str());
134   int actionId;
135   actionId = _salomeModule->createStandardAction(label,this, SLOT(OnVisualizeScalarMap()),icon,tooltip);
136   _salomeModule->createTool(actionId, presentationToolbarId);
137   _salomeModule->action(actionId)->setIconVisibleInMenu(true);
138   _salomeModule->createMenu(actionId, presentationMenuId);
139
140   label   = tr("LAB_PRESENTATION_CONTOUR");
141   tooltip = tr("TIP_PRESENTATION_CONTOUR");
142   icon    = tr(_getIconName("ICO_PRESENTATION_CONTOUR").c_str());
143   actionId = _salomeModule->createStandardAction(label,this, SLOT(OnVisualizeContour()),icon,tooltip);
144   _salomeModule->createTool(actionId, presentationToolbarId);
145   _salomeModule->action(actionId)->setIconVisibleInMenu(true);
146   _salomeModule->createMenu(actionId, presentationMenuId);
147
148   label   = tr("LAB_PRESENTATION_VECTOR_FIELD");
149   tooltip = tr("TIP_PRESENTATION_VECTOR_FIELD");
150   icon    = tr(_getIconName("ICO_PRESENTATION_VECTOR_FIELD").c_str());
151   actionId = _salomeModule->createStandardAction(label,this, SLOT(OnVisualizeVectorField()),icon,tooltip);
152   _salomeModule->createTool(actionId, presentationToolbarId);
153   _salomeModule->action(actionId)->setIconVisibleInMenu(true);
154   _salomeModule->createMenu(actionId, presentationMenuId);
155
156   label   = tr("LAB_PRESENTATION_SLICES");
157   tooltip = tr("TIP_PRESENTATION_SLICES");
158   icon    = tr(_getIconName("ICO_PRESENTATION_SLICES").c_str());
159   actionId = _salomeModule->createStandardAction(label,this, SLOT(OnVisualizeSlices()),icon,tooltip);
160   _salomeModule->createTool(actionId, presentationToolbarId);
161   _salomeModule->action(actionId)->setIconVisibleInMenu(true);
162   _salomeModule->createMenu(actionId, presentationMenuId);
163
164   label   = tr("LAB_PRESENTATION_DEFLECTION_SHAPE");
165   tooltip = tr("TIP_PRESENTATION_DEFLECTION_SHAPE");
166   icon    = tr(_getIconName("ICO_PRESENTATION_DEFLECTION_SHAPE").c_str());
167   actionId = _salomeModule->createStandardAction(label,this, SLOT(OnVisualizeDeflectionShape()),icon,tooltip);
168   _salomeModule->createTool(actionId, presentationToolbarId);
169   _salomeModule->action(actionId)->setIconVisibleInMenu(true);
170   _salomeModule->createMenu(actionId, presentationMenuId);
171
172   label   = tr("LAB_PRESENTATION_POINT_SPRITE");
173   tooltip = tr("TIP_PRESENTATION_POINT_SPRITE");
174   icon    = tr(_getIconName("ICO_PRESENTATION_POINT_SPRITE").c_str());
175   actionId = _salomeModule->createStandardAction(label,this, SLOT(OnVisualizePointSprite()),icon,tooltip);
176   _salomeModule->createTool(actionId, presentationToolbarId);
177   _salomeModule->action(actionId)->setIconVisibleInMenu(true);
178   _salomeModule->createMenu(actionId, presentationMenuId);
179
180   label   = tr("LAB_DELETE_PRESENTATION");
181   tooltip = tr("TIP_DELETE_PRESENTATION");
182   icon    = tr(_getIconName("ICO_DELETE_PRESENTATION").c_str());
183   actionId = _salomeModule->createStandardAction(label,this, SLOT(OnDeletePresentation()),icon,tooltip);
184 //  _salomeModule->createTool(actionId, presentationToolbarId);
185 //  _salomeModule->action(actionId)->setIconVisibleInMenu(true);
186   _salomeModule->createMenu(actionId, presentationMenuId);
187
188 }
189
190 MEDCALC::MEDPresentationViewMode
191 PresentationController::getSelectedViewMode()
192 {
193   if (_salomeModule->action(OPTIONS_VIEW_MODE_REPLACE_ID)->isChecked()) {
194     return MEDCALC::VIEW_MODE_REPLACE;
195   }
196   else if (_salomeModule->action(OPTIONS_VIEW_MODE_OVERLAP_ID)->isChecked()) {
197     return MEDCALC::VIEW_MODE_OVERLAP;
198   }
199   else if (_salomeModule->action(OPTIONS_VIEW_MODE_NEW_LAYOUT_ID)->isChecked()) {
200     return MEDCALC::VIEW_MODE_NEW_LAYOUT;
201   }
202   else if (_salomeModule->action(OPTIONS_VIEW_MODE_SPLIT_VIEW_ID)->isChecked()) {
203     return MEDCALC::VIEW_MODE_SPLIT_VIEW;
204   }
205   // Should not happen
206   STDLOG("Strange!! No matching view mode found - returning VIEW_MODE_REPLACE.");
207   return MEDCALC::VIEW_MODE_REPLACE;
208 }
209
210 MEDCALC::MEDPresentationColorMap
211 PresentationController::getSelectedColorMap()
212 {
213   return _widgetPresentationParameters->getColorMap();
214 }
215
216 void
217 PresentationController::visualize(PresentationEvent::EventType eventType)
218 {
219   // We need a _studyEditor updated on the active study
220   _studyEditor->updateActiveStudy();
221
222   // Get the selected objects in the study (SObject)
223   SALOME_StudyEditor::SObjectList* listOfSObject = _studyEditor->getSelectedObjects();
224
225   // For each object, emit a signal to the workspace to request a
226   // visualisation using the tui command (so that the user can see how
227   // to make a view of an object from the tui console).
228   for (int i=0; i<listOfSObject->size(); i++) {
229     SALOMEDS::SObject_var soField = listOfSObject->at(i);
230     int fieldId = -1;
231     try {
232         fieldId = _studyEditor->getParameterInt(soField,FIELD_ID);    }
233     catch(...)    { }
234     if (fieldId < 0)  // is it a field serie ?
235       {
236         int fieldSeriesId = -1;
237         try {
238             fieldSeriesId = _studyEditor->getParameterInt(soField,FIELD_SERIES_ID);      }
239         catch(...)  { }
240         // If fieldId and fieldSeriesId equals -1, then it means that it is not a field
241         // managed by the MED module, and we stop this function process.
242         if ( fieldSeriesId < 0)
243           continue;
244         MEDCALC::FieldHandlerList* fieldHandlerList = MEDFactoryClient::getDataManager()->getFieldListInFieldseries(fieldSeriesId);
245         if (fieldHandlerList->length() < 0)
246           continue;
247         // For a field series, get the first real field entry:
248         MEDCALC::FieldHandler fieldHandler = (*fieldHandlerList)[0];
249         fieldId = fieldHandler.id;
250       }
251
252     MEDCALC::FieldHandler* fieldHandler = MEDFactoryClient::getDataManager()->getFieldHandler(fieldId);
253     if (! fieldHandler) {
254       QMessageBox::warning(_salomeModule->getApp()->desktop(),
255          tr("Operation not allowed"),
256          tr("No field is defined"));
257       return;
258     }
259
260     PresentationEvent* event = new PresentationEvent();
261     event->eventtype = eventType;
262     XmedDataObject* dataObject = new XmedDataObject();
263     dataObject->setFieldHandler(*fieldHandler);
264     event->objectdata = dataObject;
265     emit presentationSignal(event); // --> WorkspaceController::processPresentationEvent
266   }
267 }
268
269 void
270 PresentationController::OnVisualizeScalarMap()
271 {
272   this->visualize(PresentationEvent::EVENT_VIEW_OBJECT_SCALAR_MAP);
273 }
274
275 void
276 PresentationController::OnVisualizeContour()
277 {
278   this->visualize(PresentationEvent::EVENT_VIEW_OBJECT_CONTOUR);
279 }
280
281 void
282 PresentationController::OnVisualizeVectorField()
283 {
284   this->visualize(PresentationEvent::EVENT_VIEW_OBJECT_VECTOR_FIELD);
285 }
286
287 void
288 PresentationController::OnVisualizeSlices()
289 {
290   this->visualize(PresentationEvent::EVENT_VIEW_OBJECT_SLICES);
291 }
292
293 void
294 PresentationController::OnVisualizeDeflectionShape()
295 {
296   this->visualize(PresentationEvent::EVENT_VIEW_OBJECT_DEFLECTION_SHAPE);
297 }
298
299 void
300 PresentationController::OnVisualizePointSprite()
301 {
302   this->visualize(PresentationEvent::EVENT_VIEW_OBJECT_POINT_SPRITE);
303 }
304
305 void
306 PresentationController::OnDeletePresentation()
307 {
308   // We need a _studyEditor updated on the active study
309   _studyEditor->updateActiveStudy();
310
311   // Get the selected objects in the study (SObject)
312   SALOME_StudyEditor::SObjectList* listOfSObject = _studyEditor->getSelectedObjects();
313
314   // For each object, emit a signal to the workspace to request pres deletion
315   for (int i=0; i<listOfSObject->size(); i++) {
316     SALOMEDS::SObject_var soPres = listOfSObject->at(i);
317     int presId = _studyEditor->getParameterInt(soPres,PRESENTATION_ID);
318     // If fieldId 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 ( presId < 0 )
321       continue;
322
323     STDLOG("Requesting deletion of presentation: ")
324     std::ostringstream oss;
325     oss << presId;
326     STDLOG("    - Pres id:          " + oss.str());
327
328     PresentationEvent* event = new PresentationEvent();
329     event->eventtype = PresentationEvent::EVENT_DELETE_PRESENTATION;
330     XmedDataObject* dataObject = new XmedDataObject();
331     dataObject->setPresentationId(presId);
332     event->objectdata = dataObject;
333     emit presentationSignal(event); // --> WorkspaceController::processPresentationEvent
334   }
335 }
336
337 void
338 PresentationController::updateTreeViewWithNewPresentation(long fieldId, long presentationId)
339 {
340   if (presentationId < 0) {
341     std::cerr << "Unknown presentation\n";
342     return;
343   }
344
345   std::string name = MEDFactoryClient::getPresentationManager()->getPresentationProperty(presentationId, "name");
346   std::string icon = std::string("ICO_") + name;
347   icon = _getIconName(icon);
348   name = tr(name.c_str()).toStdString();
349   std::string label = tr(icon.c_str()).toStdString();
350
351   SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>(_salomeModule->application()->activeStudy());
352   _PTR(Study) studyDS = study->studyDS();
353
354   _salomeModule->engine()->registerPresentation(_CAST(Study, studyDS)->GetStudy(), fieldId, name.c_str(), label.c_str(), presentationId);
355
356
357   MEDCALC::MEDPresentationViewMode viewMode = MEDFactoryClient::getPresentationManager()->getPresentationViewMode(presentationId);
358
359   // Remove sibling presentations if view mode is set to REPLACE
360   if (viewMode == MEDCALC::VIEW_MODE_REPLACE) {
361     MED_ORB::PresentationsList* presList = _salomeModule->engine()->getSiblingPresentations(_CAST(Study, studyDS)->GetStudy(), presentationId);
362     CORBA::ULong size = presList->length();
363
364     std::stringstream sstm;
365     sstm << "Removing sibling presentation(s): ";
366     for (int i = 0; i < size; ++i)
367       sstm << (*presList)[i] << "  ";
368     STDLOG(sstm.str());
369
370     for (int i = 0; i < size; ++i) {
371       PresentationEvent* event = new PresentationEvent();
372       event->eventtype = PresentationEvent::EVENT_DELETE_PRESENTATION;
373       XmedDataObject* dataObject = new XmedDataObject();
374       dataObject->setPresentationId((*presList)[i]);
375       event->objectdata = dataObject;
376       emit presentationSignal(event); // --> WorkspaceController::processPresentationEvent
377     }
378
379     delete presList;
380   }
381
382   // update Object browser
383   _salomeModule->getApp()->updateObjectBrowser(true);
384 }
385
386 void
387 PresentationController::updateTreeViewForPresentationRemoval(long presentationId)
388 {
389   if (presentationId < 0) {
390     std::cerr << "Unknown presentation\n";
391     return;
392   }
393
394   SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>(_salomeModule->application()->activeStudy());
395   _PTR(Study) studyDS = study->studyDS();
396
397   _salomeModule->engine()->unregisterPresentation(_CAST(Study, studyDS)->GetStudy(), presentationId);
398
399   // update Object browser
400   _salomeModule->getApp()->updateObjectBrowser(true);
401 }
402
403 void
404 PresentationController::processWorkspaceEvent(const MEDCALC::MedEvent* event)
405 {
406   if ( event->type == MEDCALC::EVENT_ADD_PRESENTATION ) {
407     this->updateTreeViewWithNewPresentation(event->dataId, event->presentationId);
408   }
409   else if ( event->type == MEDCALC::EVENT_REMOVE_PRESENTATION ) {
410     this->updateTreeViewForPresentationRemoval(event->presentationId);
411   }
412 }
413
414 void
415 PresentationController::showDockWidgets(bool isVisible)
416 {
417   STDLOG("Switching PresentationController visibility to: " << isVisible);
418   _dockWidget->setVisible(isVisible);
419 }