Salome HOME
Merge branch 'master' into abn/qtesting
[modules/med.git] / src / MEDCalc / gui / WorkspaceController.cxx
1 // Copyright (C) 2007-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 // Author : Guillaume Boulant (EDF)
21
22 #include "WorkspaceController.hxx"
23 #include "QtHelper.hxx"
24 #include "MEDFactoryClient.hxx"
25 #include "MEDModule.hxx"
26 #include "XmedDataModel.hxx"
27 #include "DlgAlias.hxx"
28
29 #include <SALOMEconfig.h>
30 #include CORBA_CLIENT_HEADER(MEDEventListener)
31
32 #include <SalomeApp_Application.h>
33 #include <SALOME_LifeCycleCORBA.hxx>
34 #include <SUIT_FileDlg.h>
35 #include <SUIT_Desktop.h>
36 #include <SUIT_ResourceMgr.h>
37
38 #include <QTimer>
39
40 /*!
41  * This class defines a DockWidget plugged in the SALOME application,
42  * and containing a tree view for rendering a hierarchical data
43  * model. This datamodel contains the objects used in the workspace.
44  */
45 WorkspaceController::WorkspaceController(MEDModule* salomeModule)
46   : TreeGuiManager(salomeModule->getApp(), "Workspace")
47 {
48   _salomeModule = salomeModule;
49   getDockWidgets()->getDockWidget()->setObjectName("medWorkspaceDock");
50
51   this->tabifyDockWidgets(false);
52
53   // -------------------------------------------------------------
54   // Setup the MEDEventListener to manage notification from the
55   // python console.
56
57   // We create a MEDEventListener CORBA object inside this GUI class
58   // with the role of listening events coming from the python console
59   // (or even the components if needed). The events arising in the
60   // python console are send as CORBA request to this CORBA
61   // servant. Then this object can process the event by notifying the
62   // GUI of something to update for example (using signals and slots
63   // of course).
64   _medEventListener = MEDEventListener_i::getInstance();
65   MEDCALC::MEDEventListener_ptr medEventListenerServant = _medEventListener->_this();
66
67   // We store the IOR inside the MEDDataManager to share this data
68   // with other parts of the application, in particular the python
69   // console that could retrieve this IOR using the
70   // getEventListenerIOR() function of the MEDDataManager.
71   SalomeApp_Application* salomeApp = salomeModule->getApp();
72   const char* medEventListenerIOR =
73     salomeApp->orb()->object_to_string(medEventListenerServant);
74   MEDFactoryClient::getDataManager()->setEventListenerIOR(medEventListenerIOR);
75
76   // Connect the signals emitted from the MEDEventListener to slot of
77   // this class.
78   connect(_medEventListener, SIGNAL(medEventSignal(const MEDCALC::MedEvent*)),
79     this, SLOT(processMedEvent(const MEDCALC::MedEvent*)));
80   // >>> WARN:
81   // Note that this class must be mocked (Q_OBJECT + moc file
82   // generated from header file) so that to be able to connect a
83   // signal to a slot of this class.
84
85   // -------------------------------------------------------------
86   // Customize the treeview rendering the datamodel with specific
87   // action for the popup menu
88   this->getDataTreeView()->clearActions();
89   _actionIds.display    = this->getDataTreeView()->addAction(tr("VISUALIZE_SCALAR_MAP"));
90   _actionIds.useInTui   = this->getDataTreeView()->addAction(tr("USE_IN_CONSOLE"));
91   _actionIds.exportToPv = this->getDataTreeView()->addAction(tr("EXPORT_TO_PARAVIS"));
92   _actionIds.save       = this->getDataTreeView()->addAction(tr("SAVE_AS_MED"));
93   _actionIds.remove     = this->getDataTreeView()->addAction(tr("REMOVE_FROM_WORKSPACE"));
94
95   // -------------------------------------------------------------
96   // Initialize the python console. Note that this must be done at
97   // last because the setup will try to initiate a connection to the
98   // event listener.
99   _consoleDriver = new XmedConsoleDriver(salomeModule);
100   _consoleDriver->setup();
101 }
102
103 WorkspaceController::~WorkspaceController() {
104   STDLOG("WorkspaceController::~WorkspaceController()");
105   MEDEventListener_i::release();
106 }
107
108 /**
109  * This creates the GUI actions for driving the Workspace. The
110  * WorkspaceController creates itself this actions and implements the
111  * connected slots.
112  */
113 void WorkspaceController::createActions() {
114   QWidget* dsk = _salomeModule->getApp()->desktop();
115   SUIT_ResourceMgr* resMgr = _salomeModule->getApp()->resourceMgr();
116   int toolbarId = _salomeModule->createTool("Workspace", "WorkspaceToolbar");
117
118   QString label   = tr("LAB_SAVE_WORKSPACE");
119   QString tooltip = tr("TIP_SAVE_WORKSPACE");
120   QString icon    = tr("ICO_WORKSPACE_SAVE");
121   int actionId = _salomeModule->createStandardAction(label,this,SLOT(OnSaveWorkspace()),icon,tooltip);
122   _salomeModule->createTool(actionId, toolbarId);
123
124   label   = tr("LAB_CLEAN_WORKSPACE");
125   tooltip = tr("TIP_CLEAN_WORKSPACE");
126   icon    = tr("ICO_WORKSPACE_CLEAN");
127   actionId = _salomeModule->createStandardAction(label,this,SLOT(OnCleanWorkspace()),icon,tooltip);
128   _salomeModule->createTool(actionId, toolbarId);
129 }
130
131 /*!
132  * Implementation of the slot processItemList inherited from TreeGuiManager
133  */
134 void WorkspaceController::processItemList(QStringList itemNameIdList, int actionId) {
135   if ( actionId == _actionIds.display ) {
136     STDLOG("WorkspaceController::processItemList: display");
137     this->_viewItemList(itemNameIdList);
138   }
139   else if ( actionId == _actionIds.useInTui ) {
140     STDLOG("WorkspaceController::processItemList: use");
141     this->_importItemList(itemNameIdList);
142   }
143   else if ( actionId == _actionIds.exportToPv ) {
144     STDLOG("WorkspaceController::processItemList: export");
145     this->_exportItemList(itemNameIdList);
146   }
147   else if ( actionId == _actionIds.save ) {
148     STDLOG("WorkspaceController::processItemList: save");
149     this->_saveItemList(itemNameIdList);
150   }
151   else if ( actionId == _actionIds.remove ) {
152     STDLOG("WorkspaceController::processItemList: remove");
153     this->_removeItemList(itemNameIdList);
154   }
155   else {
156     STDLOG("WorkspaceController::processItemList: ERR : action unknown ");
157   }
158 }
159
160 /*!
161  * This function import in the console all the fields associated to
162  * the model items of the specified list. "Import a fields" means
163  * "define a field proxy variable in the python context to manipulate
164  * the real field in the database".
165  */
166 void WorkspaceController::_importItemList(QStringList itemNameIdList) {
167   LOG("WorkspaceController: signal received : display item list "<<itemNameIdList);
168   QStringList::const_iterator it;
169   for (it = itemNameIdList.constBegin(); it != itemNameIdList.constEnd(); ++it) {
170     QString itemNameId = *it;
171     this->_importItem(itemNameId);
172   }
173 }
174
175 /*!
176  * This function is the unit function used to import field in the
177  * console (see _importItemList).
178  */
179 void WorkspaceController::_importItem(QString itemNameId) {
180   XmedDataModel* dataModel = (XmedDataModel*)this->getDataModel();
181   if ( dataModel == NULL ) {
182     LOG("No data model associated to this tree view");
183     return;
184   }
185
186   // We can request the dataModel to obtain the dataObject associated
187   // to this item (iteNameId is a TreeView id, Qt stuff only).
188   XmedDataObject* dataObject =
189     (XmedDataObject*)dataModel->getDataObject(QS2S(itemNameId));
190
191   if ( dataObject == NULL ) {
192     LOG("WorkspaceController: WARN! No data object associated to the item "<<itemNameId);
193     return;
194   }
195
196   // Then, we can request this data object to obtain the associated
197   // FieldHandler.
198   MEDCALC::FieldHandler* fieldHandler = dataObject->getFieldHandler();
199   STDLOG("Field: mesh="<<fieldHandler->meshname<<" name="<<fieldHandler->fieldname);
200
201   // Finally, we can import the field
202   bool askForOptions = true;
203   _importFieldIntoConsole(fieldHandler, askForOptions);
204 }
205
206 /**
207  * This function import the specified field into the tui console. This
208  * means to define a field proxy variable in the python context to
209  * manipulate the field. We can raise a gui to specify some import
210  * options or simply specify the alias (i.e. the name of the python
211  * variable).
212  */
213 void WorkspaceController::_importFieldIntoConsole(MEDCALC::FieldHandler* fieldHandler,
214               bool askForOptions,
215               const char* alias)
216 {
217   STDLOG("alias="<<alias);
218
219   // By default, the alias is the name of the field
220   QString*effectiveAlias;
221   if ( alias == NULL ) {
222     effectiveAlias = new QString(fieldHandler->fieldname);
223   }
224   else {
225     effectiveAlias = new QString(alias);
226   }
227
228   // We can propose to the user to specify some additionnal
229   // informations concerning what must be imported.
230   //
231   // In this version, we just ask the alias the field will be
232   // manipulated with. The default alias is the field name. This alias
233   // should be asked to the user to get a short name to manipulate.
234   if ( askForOptions ) {
235     DlgAlias dialog;
236     dialog.setAlias(*effectiveAlias);
237     int choice = dialog.exec();
238     if ( choice == QDialog::Rejected ) {
239       // The user decides to cancel the operation
240       return;
241     }
242     *effectiveAlias = dialog.getAlias();
243   }
244
245   //
246   // Then, the list of python commands can be written and executed to
247   // define the field in the console
248   //
249   QStringList commands;
250   commands+=QString("%1=medcalc.newFieldProxy(fieldHandlerId=%2)")
251     .arg(*effectiveAlias)
252     .arg(fieldHandler->id);
253
254   _consoleDriver->exec(commands);
255 }
256
257 /*!
258  * This function is a Qt slot connected to the signal medEventSignal
259  * emitted from the MEDEventListener. It processes events coming from
260  * the python console.
261  */
262 void WorkspaceController::processMedEvent(const MEDCALC::MedEvent* event) {
263   STDLOG("WorkspaceController::processMedEvent");
264   STDLOG("dataId  :"<<event->dataId);
265
266   XmedDataModel* dataModel = (XmedDataModel*)this->getDataModel();
267   if ( dataModel == NULL ) {
268     STDLOG("No data model associated to this tree view");
269     return;
270   }
271
272   if ( event->type == MEDCALC::EVENT_UPDATE_FIELD ) {
273     std::cout << "WorkspaceController::processMedEvent[MEDCALC::EVENT_UPDATE_FIELD]: Not implemented yet";
274   }
275   else if ( event->type == MEDCALC::EVENT_PUT_IN_WORKSPACE ) {
276     STDLOG("add new field");
277     MEDCALC::FieldHandler* fieldHandler =
278       MEDFactoryClient::getDataManager()->getFieldHandler(event->dataId);
279
280     XmedDataObject* dataObject = (XmedDataObject*)dataModel->newDataObject();
281     dataObject->setFieldHandler(*fieldHandler);
282     this->getDataTreeModel()->addData(dataObject);
283   }
284   else if ( event->type == MEDCALC::EVENT_REMOVE_FROM_WORKSPACE ) {
285     STDLOG("remove field");
286     std::map<string, DataObject*>::iterator itr = dataModel->begin();
287     for ( ; itr != dataModel->end(); ++itr) {
288       XmedDataObject* obj = dynamic_cast<XmedDataObject*>(itr->second);
289       if (obj->getFieldHandler()->id == event->dataId) {
290         std::string itemNameId = obj->getNameId();
291         this->getDataTreeModel()->removeData(obj);
292         dataModel->removeDataObject(itemNameId);
293         return;
294       }
295     }
296   }
297   else if ( event->type == MEDCALC::EVENT_CLEAN_WORKSPACE ) {
298     STDLOG("clean workspace");
299     std::map<string, DataObject*>::iterator itr = dataModel->begin();
300     for ( ; itr != dataModel->end(); ++itr) {
301       XmedDataObject* obj = dynamic_cast<XmedDataObject*>(itr->second);
302       std::string itemNameId = obj->getNameId();
303       this->getDataTreeModel()->removeData(obj);
304       dataModel->removeDataObject(itemNameId);
305     }
306   }
307   else if ( event->type == MEDCALC::EVENT_ADD_DATASOURCE ) {
308     emit workspaceSignal(event); // forward to DatasourceController
309   }
310   else if ( event->type == MEDCALC::EVENT_ADD_PRESENTATION ) {
311     emit workspaceSignal(event); // forward to PresentationController
312   }
313   else if ( event->type == MEDCALC::EVENT_REMOVE_PRESENTATION ) {
314     emit workspaceSignal(event); // forward to PresentationController
315   }
316   else if ( event->type == MEDCALC::EVENT_PLAY_TEST ) {
317     emit workspaceSignal(event); // forward to TestController
318   }
319   else if ( event->type == MEDCALC::EVENT_QUIT_SALOME ) {
320     emit workspaceSignal(event); // forward to TestController
321   }
322 }
323
324 /*!
325  * This function save a list of fields in a med file. The med file
326  * name is requested to the user using a file chooser dialog box
327  */
328 void WorkspaceController::_saveItemList(QStringList itemNameIdList) {
329   XmedDataProcessor* dataProcessor = new XmedDataProcessor(this->getDataModel());
330   dataProcessor->process(itemNameIdList);
331   MEDCALC::FieldIdList_var fieldIdList = dataProcessor->getResultingFieldIdList();
332   delete dataProcessor;
333
334   QStringList filter;
335   filter.append(tr("FILE_FILTER_MED"));
336   QString filename = SUIT_FileDlg::getFileName(_salomeModule->getApp()->desktop(),
337                                                "",
338                                                filter,
339                                                tr("SAVE_SELECTED_FIELDS"),
340                                                false);
341
342   if ( filename.isEmpty() ) return;
343
344   MEDFactoryClient::getDataManager()->saveFields(QCHARSTAR(filename), fieldIdList);
345 }
346
347 /*!
348  * This function remove the selected item from workspace.
349  */
350 void WorkspaceController::_removeItemList(QStringList itemNameIdList) {
351   XmedDataModel* dataModel = (XmedDataModel*)this->getDataModel();
352   if ( dataModel == NULL ) {
353     LOG("No data model associated to this tree view");
354     return;
355   }
356
357   // __GBO__: In this version, we consider only the first field in the selection
358   QString itemNameId = itemNameIdList[0];
359
360   // We can request the dataModel to obtain the dataObject associated
361   // to this item (iteNameId is a TreeView id, Qt stuff only).
362   XmedDataObject* dataObject =
363     (XmedDataObject*)dataModel->getDataObject(QS2S(itemNameId));
364
365   if ( dataObject == NULL ) {
366     LOG("WorkspaceController: WARN! No data object associated to the item "<<itemNameId);
367     return;
368   }
369
370   // Then, we can request this data object to obtain the associated
371   // FieldHandler.
372   MEDCALC::FieldHandler* fieldHandler = dataObject->getFieldHandler();
373   STDLOG("Field: mesh="<<fieldHandler->meshname<<" name="<<fieldHandler->fieldname);
374
375   // Remove the field variable from console
376   QStringList commands;
377   commands+=QString("removeFromWorkspace(accessField(%1))").arg(fieldHandler->id);
378   _consoleDriver->exec(commands);
379
380   // Finally, we can remove the field from tree data model and tree view
381   this->getDataTreeModel()->removeData(dataObject);
382   dataModel->removeDataObject(QS2S(itemNameId));
383 }
384
385 /**
386  * This function export the list of specified field item to PARAVIS
387  * module. This consists in create a med file gathering the selected
388  * items, then to import this file in PARAVIS, and finally to create a
389  * scalar map of the first item to start the job.
390  */
391 void WorkspaceController::_exportItemList(QStringList itemNameIdList) {
392   XmedDataProcessor* dataProcessor = new XmedDataProcessor(this->getDataModel());
393   dataProcessor->process(itemNameIdList);
394   MEDCALC::FieldIdList_var fieldIdList = dataProcessor->getResultingFieldIdList();
395   delete dataProcessor;
396
397   // _GBO_ We use a temporary file to proceed with this export to
398   // paravis. I'm sure it could be better in a futur version or when I
399   // will get a better understanding of paravis API.
400   const char* tmpfilename = "/tmp/medcalc_export2paravis.med";
401   MEDFactoryClient::getDataManager()->saveFields(tmpfilename, fieldIdList);
402
403   // We import the whole file but create a scalar map for the first
404   // selected field only (it's just an export to continue the job in
405   // paravis)
406   XmedDataModel* dataModel = (XmedDataModel*)this->getDataModel();
407   if ( dataModel == NULL ) {
408     STDLOG("No data model associated to this tree view");
409     return;
410   }
411   QString itemNameId = itemNameIdList[0];
412   XmedDataObject* dataObject = (XmedDataObject*)dataModel->getDataObject(QS2S(itemNameId));
413   if ( dataObject == NULL ) {
414     LOG("WorkspaceController: WARN! No data object associated to the item "<<itemNameId);
415     return;
416   }
417   MEDCALC::FieldHandler* fieldHandler = dataObject->getFieldHandler();
418   QStringList commands;
419   /*
420   commands+=QString("from xmed.driver_pvis import pvis_scalarmap");
421   commands+=QString("pvis_scalarmap('%1','%2','%3',%4,%5)")
422     .arg(tmpfilename)
423     .arg(QString(fieldHandler->meshname))
424     .arg(QString(fieldHandler->fieldname))
425     .arg(fieldHandler->type)
426     .arg(fieldHandler->iteration);
427   */
428   commands += "print 'Not implemented yet'";
429   _consoleDriver->exec(commands);
430
431 }
432
433 /*!
434  * This function sends a request to the SALOME data visualisation
435  * (module VISU or PARAVIS) for displaying a scalar map of the fields
436  * associated to the model items in the specified list.
437  *
438  */
439 void WorkspaceController::_viewItemList(QStringList itemNameIdList) {
440
441   // __GBO__: In this version, we consider only the first field in the selection
442   QString itemNameId = itemNameIdList[0];
443
444   XmedDataModel* dataModel = (XmedDataModel*)this->getDataModel();
445   if ( dataModel == NULL ) {
446     LOG("No data model associated to this tree view");
447     return;
448   }
449
450   // We can request the dataModel to obtain the dataObject associated
451   // to this item (iteNameId is a TreeView id, Qt stuff only).
452   XmedDataObject* dataObject =
453     (XmedDataObject*)dataModel->getDataObject(QS2S(itemNameId));
454   if ( dataObject == NULL ) {
455     LOG("WorkspaceController: WARN! No data object associated to the item "<<itemNameId);
456     return;
457   }
458
459   // Then, we can request this data object to obtain the associated
460   // FieldHandler.
461   MEDCALC::FieldHandler* fieldHandler = dataObject->getFieldHandler();
462
463   // And finally, we can create the set of medcalc instructions to
464   // generate the scalar map on this field.
465   QStringList commands;
466   //commands+=QString("view(accessField(%1))").arg(fieldHandler->id);
467   commands += "print 'Not implemented yet'";
468   _consoleDriver->exec(commands);
469 }
470
471 /**
472  * This slot can process the event coming from the
473  * DatasourceController. The connection between the datasource signal
474  * and this slot is realized by the main class MEDModule.
475  */
476 void WorkspaceController::processDatasourceEvent(const DatasourceEvent* event) {
477   XmedDataModel* dataModel = (XmedDataModel*)this->getDataModel();
478   if ( dataModel == NULL ) {
479     STDLOG("No data model associated to this tree view");
480     return;
481   }
482
483   // >>>
484   // __GBO__ To know what to do we should test the type, because the
485   // object could be a mesh, a timeseries or a single field. We test
486   // here the case of a single field. Moreover, there could have
487   // options such that "change the underlying mesh".
488   // <<<
489
490   XmedDataObject* dataObject = event->objectdata;
491
492   if ( event->eventtype == DatasourceEvent::EVENT_IMPORT_OBJECT ) {
493     std::cout << "IMPORT object in workspace: " << dataObject->toString() << std::endl;
494     STDLOG("IMPORT object in workspace:\n"<<dataObject->toString());
495     // _GBO_ QUESTION: tag automatically the object as a peristant object ??
496     // We first add the data object to the internal data model
497     dataModel->addDataObject(dataObject);
498     // Then we request the tree view to consider this new object
499     this->getDataTreeModel()->addData(dataObject);
500   }
501   else if ( event->eventtype == DatasourceEvent::EVENT_USE_OBJECT ) {
502     STDLOG("USE object in workspace:\n"<<dataObject->toString());
503     // We first add the data object to the internal data model
504     dataModel->addDataObject(dataObject);
505     // Then we request the tree view to consider this new object
506     this->getDataTreeModel()->addData(dataObject);
507
508     // We define a proxy for this object in the tui console.
509     STDLOG("Define a proxy variable in the console with name : "<<QCHARSTAR(event->objectalias));
510     bool askForOptions = false;
511     _importFieldIntoConsole(dataObject->getFieldHandler(),
512           askForOptions,
513           QCHARSTAR(event->objectalias));
514   }
515   else if ( event->eventtype == DatasourceEvent::EVENT_ADD_DATASOURCE ) {
516     QStringList commands;
517     commands += QString("source_id = medcalc.LoadDataSource('%1')").arg(event->objectalias);
518     commands += QString("source_id");
519     _consoleDriver->exec(commands);
520   }
521   else if ( event->eventtype == DatasourceEvent::EVENT_ADD_IMAGE_AS_DATASOURCE ) {
522     QStringList commands;
523     commands += QString("source_id = medcalc.LoadImageAsDataSource('%1')").arg(event->objectalias);
524     commands += QString("source_id");
525     _consoleDriver->exec(commands);
526   }
527   else {
528     STDLOG("The event "<<event->eventtype<<" is not implemented yet");
529   }
530 }
531
532 QString
533 WorkspaceController::_getViewMode()
534 {
535   MEDCALC::MEDPresentationViewMode viewMode = _salomeModule->getSelectedViewMode();
536   switch(viewMode) {
537   case MEDCALC::VIEW_MODE_REPLACE: return "MEDCALC.VIEW_MODE_REPLACE";
538   case MEDCALC::VIEW_MODE_OVERLAP: return "MEDCALC.VIEW_MODE_OVERLAP";
539   case MEDCALC::VIEW_MODE_NEW_LAYOUT: return "MEDCALC.VIEW_MODE_NEW_LAYOUT";
540   case MEDCALC::VIEW_MODE_SPLIT_VIEW: return "MEDCALC.VIEW_MODE_SPLIT_VIEW";
541   }
542   return QString();
543 }
544
545 QString
546 WorkspaceController::_getColorMap()
547 {
548   MEDCALC::MEDPresentationColorMap colorMap = _salomeModule->getSelectedColorMap();
549   switch(colorMap) {
550   case MEDCALC::COLOR_MAP_BLUE_TO_RED_RAINBOW: return "MEDCALC.COLOR_MAP_BLUE_TO_RED_RAINBOW";
551   case MEDCALC::COLOR_MAP_COOL_TO_WARM: return "MEDCALC.COLOR_MAP_COOL_TO_WARM";
552   }
553   return QString();
554 }
555
556 /**
557  * This slot can process the event coming from the
558  * DatasourceController. The connection between the datasource signal
559  * and this slot is realized by the main class MEDModule.
560  */
561 void WorkspaceController::processPresentationEvent(const PresentationEvent* event) {
562   XmedDataModel* dataModel = (XmedDataModel*)this->getDataModel();
563   if ( dataModel == NULL ) {
564     STDLOG("No data model associated to this tree view");
565     return;
566   }
567
568   // >>>
569   // __GBO__ To know what to do we should test the type, because the
570   // object could be a mesh, a timeseries or a single field. We test
571   // here the case of a single field. Moreover, there could have
572   // options such that "change the underlying mesh".
573   // <<<
574
575   XmedDataObject* dataObject = event->objectdata;
576
577   // --> Send commands to SALOME Python console
578   if ( event->eventtype == PresentationEvent::EVENT_VIEW_OBJECT_SCALAR_MAP ) {
579     QString viewMode = _getViewMode();
580     //QString displayedInfo = ; // from PresentationController combobox
581     //QString scalarBarRange = ; // from PresentationController spinbox
582     QString colorMap = _getColorMap();
583     MEDCALC::FieldHandler* fieldHandler = dataObject->getFieldHandler();
584     QStringList commands;
585     commands += QString("presentation_id = medcalc.MakeScalarMap(accessField(%1), %2, colorMap=%3)").arg(fieldHandler->id).arg(viewMode).arg(colorMap);
586     commands += QString("presentation_id");
587     _consoleDriver->exec(commands);
588   }
589   else if ( event->eventtype == PresentationEvent::EVENT_VIEW_OBJECT_CONTOUR ) {
590     QString viewMode = _getViewMode();
591     MEDCALC::FieldHandler* fieldHandler = dataObject->getFieldHandler();
592     QStringList commands;
593     commands += QString("presentation_id = medcalc.MakeContour(accessField(%1), %2)").arg(fieldHandler->id).arg(viewMode);
594     commands += QString("presentation_id");
595     _consoleDriver->exec(commands);
596   }
597   else if ( event->eventtype == PresentationEvent::EVENT_VIEW_OBJECT_VECTOR_FIELD ) {
598     QString viewMode = _getViewMode();
599     MEDCALC::FieldHandler* fieldHandler = dataObject->getFieldHandler();
600     QStringList commands;
601     commands += QString("presentation_id = medcalc.MakeVectorField(accessField(%1), %2)").arg(fieldHandler->id).arg(viewMode);
602     commands += QString("presentation_id");
603     _consoleDriver->exec(commands);
604   }
605   else if ( event->eventtype == PresentationEvent::EVENT_VIEW_OBJECT_SLICES ) {
606     QString viewMode = _getViewMode();
607     MEDCALC::FieldHandler* fieldHandler = dataObject->getFieldHandler();
608     QStringList commands;
609     commands += QString("presentation_id = medcalc.MakeSlices(accessField(%1), %2)").arg(fieldHandler->id).arg(viewMode);
610     commands += QString("presentation_id");
611     _consoleDriver->exec(commands);
612   }
613   else if ( event->eventtype == PresentationEvent::EVENT_VIEW_OBJECT_DEFLECTION_SHAPE ) {
614     QString viewMode = _getViewMode();
615     MEDCALC::FieldHandler* fieldHandler = dataObject->getFieldHandler();
616     QStringList commands;
617     commands += QString("presentation_id = medcalc.MakeDeflectionShape(accessField(%1), %2)").arg(fieldHandler->id).arg(viewMode);
618     commands += QString("presentation_id");
619     _consoleDriver->exec(commands);
620   }
621   else if ( event->eventtype == PresentationEvent::EVENT_VIEW_OBJECT_POINT_SPRITE ) {
622     QString viewMode = _getViewMode();
623     MEDCALC::FieldHandler* fieldHandler = dataObject->getFieldHandler();
624     QStringList commands;
625     commands += QString("presentation_id = medcalc.MakePointSprite(accessField(%1), %2)").arg(fieldHandler->id).arg(viewMode);
626     commands += QString("presentation_id");
627     _consoleDriver->exec(commands);
628   }
629   else {
630     STDLOG("The event "<<event->eventtype<<" is not implemented yet");
631   }
632 }
633
634 void
635 WorkspaceController::processProcessingEvent(const ProcessingEvent* event)
636 {
637   XmedDataModel* dataModel = (XmedDataModel*)this->getDataModel();
638   if ( dataModel == NULL ) {
639     STDLOG("No data model associated to this tree view");
640     return;
641   }
642
643   // >>>
644   // __GBO__ To know what to do we should test the type, because the
645   // object could be a mesh, a timeseries or a single field. We test
646   // here the case of a single field. Moreover, there could have
647   // options such that "change the underlying mesh".
648   // <<<
649
650   XmedDataObject* dataObject = event->objectdata;
651
652   if ( event->eventtype == ProcessingEvent::EVENT_IMPORT_OBJECT ) {
653     std::cout << "IMPORT object in workspace: " << dataObject->toString() << std::endl;
654     STDLOG("IMPORT object in workspace:\n"<<dataObject->toString());
655     // _GBO_ QUESTION: tag automatically the object as a peristant object ??
656     // We first add the data object to the internal data model
657     dataModel->addDataObject(dataObject);
658     // Then we request the tree view to consider this new object
659     this->getDataTreeModel()->addData(dataObject);
660   }
661 }
662
663 void WorkspaceController::OnSaveWorkspace() {
664
665   // Dialog to get the filename where the workspace must be saved into
666   QStringList filter;
667   filter.append(tr("FILE_FILTER_MED"));
668
669   QString filename = SUIT_FileDlg::getFileName(_salomeModule->getApp()->desktop(),
670                                                "",
671                                                filter,
672                                                tr("SAVE_WORKSPACE_DATA"),
673                                                false);
674
675   if ( filename.isEmpty() ) return;
676
677   STDLOG("OnWorkspaceSave: save the workspace in the file " << QCHARSTAR(filename));
678   QStringList commands;
679   commands+=QString("saveWorkspace('%1')").arg(filename);
680   _consoleDriver->exec(commands);
681 }
682
683 #include <QMessageBox>
684 void WorkspaceController::OnCleanWorkspace() {
685   // Remove field from console
686   QStringList commands;
687   commands += QString("cleanWorkspace()");
688   _consoleDriver->exec(commands);
689 }