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