Salome HOME
Update copyrights
[modules/med.git] / src / MEDCalc / gui / WorkspaceController.cxx
index c7d281002520951dd0e440aec893bb3d2dd6784f..97235c63a3b8835eb735044ade2eb46aee44912e 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2015  CEA/DEN, EDF R&D
+// Copyright (C) 2007-2019  CEA/DEN, EDF R&D
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
@@ -22,6 +22,7 @@
 #include "WorkspaceController.hxx"
 #include "QtHelper.hxx"
 #include "MEDFactoryClient.hxx"
+#include "MEDModule.hxx"
 #include "XmedDataModel.hxx"
 #include "DlgAlias.hxx"
 
 #include <SALOME_LifeCycleCORBA.hxx>
 #include <SUIT_FileDlg.h>
 #include <SUIT_Desktop.h>
+#include <SUIT_ResourceMgr.h>
+
+#include <QTimer>
+#include <QMessageBox>
+
+#include "MEDLoader.hxx"
+using namespace MEDCoupling;
+#include "MEDDataManager_i.hxx"
 
 /*!
  * This class defines a DockWidget plugged in the SALOME application,
  * and containing a tree view for rendering a hierarchical data
  * model. This datamodel contains the objects used in the workspace.
  */
-WorkspaceController::WorkspaceController(StandardApp_Module * salomeModule)
+WorkspaceController::WorkspaceController(MEDModule* salomeModule)
   : TreeGuiManager(salomeModule->getApp(), "Workspace")
 {
   _salomeModule = salomeModule;
@@ -64,8 +73,8 @@ WorkspaceController::WorkspaceController(StandardApp_Module * salomeModule)
   // with other parts of the application, in particular the python
   // console that could retrieve this IOR using the
   // getEventListenerIOR() function of the MEDDataManager.
-  SalomeApp_Application * salomeApp = salomeModule->getApp();
-  const char * medEventListenerIOR =
+  SalomeApp_Application* salomeApp = salomeModule->getApp();
+  const char* medEventListenerIOR =
     salomeApp->orb()->object_to_string(medEventListenerServant);
   MEDFactoryClient::getDataManager()->setEventListenerIOR(medEventListenerIOR);
 
@@ -92,11 +101,12 @@ WorkspaceController::WorkspaceController(StandardApp_Module * salomeModule)
   // Initialize the python console. Note that this must be done at
   // last because the setup will try to initiate a connection to the
   // event listener.
-  _consoleDriver = new XmedConsoleDriver(salomeApp);
+  _consoleDriver = new XmedConsoleDriver(salomeModule);
   _consoleDriver->setup();
 }
 
 WorkspaceController::~WorkspaceController() {
+  STDLOG("WorkspaceController::~WorkspaceController()");
   MEDEventListener_i::release();
 }
 
@@ -106,18 +116,21 @@ WorkspaceController::~WorkspaceController() {
  * connected slots.
  */
 void WorkspaceController::createActions() {
+  QWidget* dsk = _salomeModule->getApp()->desktop();
+  SUIT_ResourceMgr* resMgr = _salomeModule->getApp()->resourceMgr();
+  int toolbarId = _salomeModule->createTool("Workspace", "WorkspaceToolbar");
 
   QString label   = tr("LAB_SAVE_WORKSPACE");
   QString tooltip = tr("TIP_SAVE_WORKSPACE");
   QString icon    = tr("ICO_WORKSPACE_SAVE");
   int actionId = _salomeModule->createStandardAction(label,this,SLOT(OnSaveWorkspace()),icon,tooltip);
-  _salomeModule->addActionInToolbar(actionId);
+  _salomeModule->createTool(actionId, toolbarId);
 
   label   = tr("LAB_CLEAN_WORKSPACE");
   tooltip = tr("TIP_CLEAN_WORKSPACE");
   icon    = tr("ICO_WORKSPACE_CLEAN");
   actionId = _salomeModule->createStandardAction(label,this,SLOT(OnCleanWorkspace()),icon,tooltip);
-  _salomeModule->addActionInToolbar(actionId);
+  _salomeModule->createTool(actionId, toolbarId);
 }
 
 /*!
@@ -169,7 +182,7 @@ void WorkspaceController::_importItemList(QStringList itemNameIdList) {
  * console (see _importItemList).
  */
 void WorkspaceController::_importItem(QString itemNameId) {
-  XmedDataModel * dataModel = (XmedDataModel *)this->getDataModel();
+  XmedDataModel* dataModel = (XmedDataModel*)this->getDataModel();
   if ( dataModel == NULL ) {
     LOG("No data model associated to this tree view");
     return;
@@ -177,8 +190,8 @@ void WorkspaceController::_importItem(QString itemNameId) {
 
   // We can request the dataModel to obtain the dataObject associated
   // to this item (iteNameId is a TreeView id, Qt stuff only).
-  XmedDataObject * dataObject =
-    (XmedDataObject *)dataModel->getDataObject(QS2S(itemNameId));
+  XmedDataObject* dataObject =
+    (XmedDataObject*)dataModel->getDataObject(QS2S(itemNameId));
 
   if ( dataObject == NULL ) {
     LOG("WorkspaceController: WARN! No data object associated to the item "<<itemNameId);
@@ -187,7 +200,7 @@ void WorkspaceController::_importItem(QString itemNameId) {
 
   // Then, we can request this data object to obtain the associated
   // FieldHandler.
-  MEDCALC::FieldHandler * fieldHandler = dataObject->getFieldHandler();
+  MEDCALC::FieldHandler* fieldHandler = dataObject->getFieldHandler();
   STDLOG("Field: mesh="<<fieldHandler->meshname<<" name="<<fieldHandler->fieldname);
 
   // Finally, we can import the field
@@ -202,14 +215,14 @@ void WorkspaceController::_importItem(QString itemNameId) {
  * options or simply specify the alias (i.e. the name of the python
  * variable).
  */
-void WorkspaceController::_importFieldIntoConsole(MEDCALC::FieldHandler * fieldHandler,
+void WorkspaceController::_importFieldIntoConsole(MEDCALC::FieldHandler* fieldHandler,
               bool askForOptions,
-              const char * alias)
+              const char* alias)
 {
   STDLOG("alias="<<alias);
 
   // By default, the alias is the name of the field
-  QString *effectiveAlias;
+  QString*effectiveAlias;
   if ( alias == NULL ) {
     effectiveAlias = new QString(fieldHandler->fieldname);
   }
@@ -217,8 +230,8 @@ void WorkspaceController::_importFieldIntoConsole(MEDCALC::FieldHandler * fieldH
     effectiveAlias = new QString(alias);
   }
 
-  // We can propose to the user to specify some additionnal
-  // informations concerning what must be imported.
+  // We can propose to the user to specify some additional
+  // information concerning what must be imported.
   //
   // In this version, we just ask the alias the field will be
   // manipulated with. The default alias is the field name. This alias
@@ -251,11 +264,11 @@ void WorkspaceController::_importFieldIntoConsole(MEDCALC::FieldHandler * fieldH
  * emitted from the MEDEventListener. It processes events coming from
  * the python console.
  */
-void WorkspaceController::processMedEvent(const MEDCALC::MedEvent * event) {
+void WorkspaceController::processMedEvent(const MEDCALC::MedEvent* event) {
   STDLOG("WorkspaceController::processMedEvent");
   STDLOG("dataId  :"<<event->dataId);
 
-  XmedDataModel * dataModel = (XmedDataModel *)this->getDataModel();
+  XmedDataModel* dataModel = (XmedDataModel*)this->getDataModel();
   if ( dataModel == NULL ) {
     STDLOG("No data model associated to this tree view");
     return;
@@ -266,16 +279,16 @@ void WorkspaceController::processMedEvent(const MEDCALC::MedEvent * event) {
   }
   else if ( event->type == MEDCALC::EVENT_PUT_IN_WORKSPACE ) {
     STDLOG("add new field");
-    MEDCALC::FieldHandler * fieldHandler =
+    MEDCALC::FieldHandler* fieldHandler =
       MEDFactoryClient::getDataManager()->getFieldHandler(event->dataId);
 
-    XmedDataObject * dataObject = (XmedDataObject *)dataModel->newDataObject();
+    XmedDataObject* dataObject = (XmedDataObject*)dataModel->newDataObject();
     dataObject->setFieldHandler(*fieldHandler);
     this->getDataTreeModel()->addData(dataObject);
   }
   else if ( event->type == MEDCALC::EVENT_REMOVE_FROM_WORKSPACE ) {
     STDLOG("remove field");
-    std::map<string, DataObject *>::iterator itr = dataModel->begin();
+    std::map<string, DataObject*>::iterator itr = dataModel->begin();
     for ( ; itr != dataModel->end(); ++itr) {
       XmedDataObject* obj = dynamic_cast<XmedDataObject*>(itr->second);
       if (obj->getFieldHandler()->id == event->dataId) {
@@ -288,7 +301,7 @@ void WorkspaceController::processMedEvent(const MEDCALC::MedEvent * event) {
   }
   else if ( event->type == MEDCALC::EVENT_CLEAN_WORKSPACE ) {
     STDLOG("clean workspace");
-    std::map<string, DataObject *>::iterator itr = dataModel->begin();
+    std::map<string, DataObject*>::iterator itr = dataModel->begin();
     for ( ; itr != dataModel->end(); ++itr) {
       XmedDataObject* obj = dynamic_cast<XmedDataObject*>(itr->second);
       std::string itemNameId = obj->getNameId();
@@ -300,9 +313,56 @@ void WorkspaceController::processMedEvent(const MEDCALC::MedEvent * event) {
     emit workspaceSignal(event); // forward to DatasourceController
   }
   else if ( event->type == MEDCALC::EVENT_ADD_PRESENTATION ) {
-    emit workspaceSignal(event); // forward to DatasourceController
+    emit workspaceSignal(event); // forward to PresentationController
+  }
+  else if ( event->type == MEDCALC::EVENT_REMOVE_PRESENTATION ) {
+    emit workspaceSignal(event); // forward to PresentationController
+  }
+  else if ( event->type == MEDCALC::EVENT_MODIFY_PRESENTATION ) {
+      emit workspaceSignal(event); // forward to PresentationController
   }
+  else if ( event->type == MEDCALC::EVENT_CHANGE_UNDERLYING_MESH
+            || event->type == MEDCALC::EVENT_INTERPOLATE_FIELD ) {
+    int fieldId = event->dataId;
+    MEDCALC::FieldHandler* fieldHandler = MEDFactoryClient::getDataManager()->getFieldHandler(fieldId);
+    XmedDataObject* dataObject = new XmedDataObject();
+    dataObject->setFieldHandler(*fieldHandler);
+    std::cout << "IMPORT object in workspace: " << dataObject->toString() << std::endl;
+    STDLOG("IMPORT object in workspace:\n"<<dataObject->toString());
+    // _GBO_ QUESTION: tag automatically the object as a peristant object ??
+    // We first add the data object to the internal data model
+    dataModel->addDataObject(dataObject);
+    // Then we request the tree view to consider this new object
+    this->getDataTreeModel()->addData(dataObject);
+
+    // Workaround to visualize the result
+    MEDCouplingFieldDouble* fieldDouble = MEDDataManager_i::getInstance()->getFieldDouble(fieldHandler);
+    std::string filename = std::tmpnam(NULL);
+    WriteField(filename.c_str(), fieldDouble, true);
 
+    QStringList commands;
+    commands += QString("source_id = medcalc.LoadDataSource('%1')").arg(filename.c_str());
+    commands += QString("source_id");
+    commands += QString("mesh_id = medcalc.GetFirstMeshFromDataSource(source_id)");
+    commands += QString("mesh_id");
+    commands += QString("field_id = medcalc.GetFirstFieldFromMesh(mesh_id)");
+    commands += QString("field_id");
+    commands += QString("presentation_id = medcalc.MakeScalarMap(accessField(field_id), viewMode=MEDCALC.VIEW_MODE_NEW_LAYOUT)");
+    commands += QString("presentation_id");
+    _consoleDriver->exec(commands);
+  }
+  else if ( event->type == MEDCALC::EVENT_PLAY_TEST ) {
+    emit workspaceSignal(event); // forward to TestController
+  }
+  else if ( event->type == MEDCALC::EVENT_QUIT_SALOME ) {
+    emit workspaceSignal(event); // forward to TestController
+  }
+  else if ( event->type == MEDCALC::EVENT_ERROR ) {
+      std::string msg(event->msg);
+      QMessageBox::warning(_salomeModule->getApp()->desktop(), "Error", QString::fromStdString(msg));
+  }
+  else
+    STDLOG("WorkspaceController::processMedEvent(): Unhandled event!!!");
 }
 
 /*!
@@ -310,7 +370,7 @@ void WorkspaceController::processMedEvent(const MEDCALC::MedEvent * event) {
  * name is requested to the user using a file chooser dialog box
  */
 void WorkspaceController::_saveItemList(QStringList itemNameIdList) {
-  XmedDataProcessor * dataProcessor = new XmedDataProcessor(this->getDataModel());
+  XmedDataProcessor* dataProcessor = new XmedDataProcessor(this->getDataModel());
   dataProcessor->process(itemNameIdList);
   MEDCALC::FieldIdList_var fieldIdList = dataProcessor->getResultingFieldIdList();
   delete dataProcessor;
@@ -332,7 +392,7 @@ void WorkspaceController::_saveItemList(QStringList itemNameIdList) {
  * This function remove the selected item from workspace.
  */
 void WorkspaceController::_removeItemList(QStringList itemNameIdList) {
-  XmedDataModel * dataModel = (XmedDataModel *)this->getDataModel();
+  XmedDataModel* dataModel = (XmedDataModel*)this->getDataModel();
   if ( dataModel == NULL ) {
     LOG("No data model associated to this tree view");
     return;
@@ -343,8 +403,8 @@ void WorkspaceController::_removeItemList(QStringList itemNameIdList) {
 
   // We can request the dataModel to obtain the dataObject associated
   // to this item (iteNameId is a TreeView id, Qt stuff only).
-  XmedDataObject * dataObject =
-    (XmedDataObject *)dataModel->getDataObject(QS2S(itemNameId));
+  XmedDataObject* dataObject =
+    (XmedDataObject*)dataModel->getDataObject(QS2S(itemNameId));
 
   if ( dataObject == NULL ) {
     LOG("WorkspaceController: WARN! No data object associated to the item "<<itemNameId);
@@ -353,7 +413,7 @@ void WorkspaceController::_removeItemList(QStringList itemNameIdList) {
 
   // Then, we can request this data object to obtain the associated
   // FieldHandler.
-  MEDCALC::FieldHandler * fieldHandler = dataObject->getFieldHandler();
+  MEDCALC::FieldHandler* fieldHandler = dataObject->getFieldHandler();
   STDLOG("Field: mesh="<<fieldHandler->meshname<<" name="<<fieldHandler->fieldname);
 
   // Remove the field variable from console
@@ -373,7 +433,7 @@ void WorkspaceController::_removeItemList(QStringList itemNameIdList) {
  * scalar map of the first item to start the job.
  */
 void WorkspaceController::_exportItemList(QStringList itemNameIdList) {
-  XmedDataProcessor * dataProcessor = new XmedDataProcessor(this->getDataModel());
+  XmedDataProcessor* dataProcessor = new XmedDataProcessor(this->getDataModel());
   dataProcessor->process(itemNameIdList);
   MEDCALC::FieldIdList_var fieldIdList = dataProcessor->getResultingFieldIdList();
   delete dataProcessor;
@@ -381,24 +441,24 @@ void WorkspaceController::_exportItemList(QStringList itemNameIdList) {
   // _GBO_ We use a temporary file to proceed with this export to
   // paravis. I'm sure it could be better in a futur version or when I
   // will get a better understanding of paravis API.
-  const char * tmpfilename = "/tmp/medcalc_export2paravis.med";
+  const char* tmpfilename = "/tmp/medcalc_export2paravis.med";
   MEDFactoryClient::getDataManager()->saveFields(tmpfilename, fieldIdList);
 
   // We import the whole file but create a scalar map for the first
   // selected field only (it's just an export to continue the job in
   // paravis)
-  XmedDataModel * dataModel = (XmedDataModel *)this->getDataModel();
+  XmedDataModel* dataModel = (XmedDataModel*)this->getDataModel();
   if ( dataModel == NULL ) {
     STDLOG("No data model associated to this tree view");
     return;
   }
   QString itemNameId = itemNameIdList[0];
-  XmedDataObject * dataObject = (XmedDataObject *)dataModel->getDataObject(QS2S(itemNameId));
+  XmedDataObject* dataObject = (XmedDataObject*)dataModel->getDataObject(QS2S(itemNameId));
   if ( dataObject == NULL ) {
     LOG("WorkspaceController: WARN! No data object associated to the item "<<itemNameId);
     return;
   }
-  MEDCALC::FieldHandler * fieldHandler = dataObject->getFieldHandler();
+  MEDCALC::FieldHandler* fieldHandler = dataObject->getFieldHandler();
   QStringList commands;
   /*
   commands+=QString("from xmed.driver_pvis import pvis_scalarmap");
@@ -409,7 +469,7 @@ void WorkspaceController::_exportItemList(QStringList itemNameIdList) {
     .arg(fieldHandler->type)
     .arg(fieldHandler->iteration);
   */
-  commands += "print 'Not implemented yet'";
+  commands += "print('Not implemented yet')";
   _consoleDriver->exec(commands);
 
 }
@@ -425,7 +485,7 @@ void WorkspaceController::_viewItemList(QStringList itemNameIdList) {
   // __GBO__: In this version, we consider only the first field in the selection
   QString itemNameId = itemNameIdList[0];
 
-  XmedDataModel * dataModel = (XmedDataModel *)this->getDataModel();
+  XmedDataModel* dataModel = (XmedDataModel*)this->getDataModel();
   if ( dataModel == NULL ) {
     LOG("No data model associated to this tree view");
     return;
@@ -433,8 +493,8 @@ void WorkspaceController::_viewItemList(QStringList itemNameIdList) {
 
   // We can request the dataModel to obtain the dataObject associated
   // to this item (iteNameId is a TreeView id, Qt stuff only).
-  XmedDataObject * dataObject =
-    (XmedDataObject *)dataModel->getDataObject(QS2S(itemNameId));
+  XmedDataObject* dataObject =
+    (XmedDataObject*)dataModel->getDataObject(QS2S(itemNameId));
   if ( dataObject == NULL ) {
     LOG("WorkspaceController: WARN! No data object associated to the item "<<itemNameId);
     return;
@@ -442,13 +502,13 @@ void WorkspaceController::_viewItemList(QStringList itemNameIdList) {
 
   // Then, we can request this data object to obtain the associated
   // FieldHandler.
-  MEDCALC::FieldHandler * fieldHandler = dataObject->getFieldHandler();
+  MEDCALC::FieldHandler* fieldHandler = dataObject->getFieldHandler();
 
   // And finally, we can create the set of medcalc instructions to
   // generate the scalar map on this field.
   QStringList commands;
   //commands+=QString("view(accessField(%1))").arg(fieldHandler->id);
-  commands += "print 'Not implemented yet'";
+  commands += "print('Not implemented yet')";
   _consoleDriver->exec(commands);
 }
 
@@ -457,8 +517,8 @@ void WorkspaceController::_viewItemList(QStringList itemNameIdList) {
  * DatasourceController. The connection between the datasource signal
  * and this slot is realized by the main class MEDModule.
  */
-void WorkspaceController::processDatasourceEvent(const DatasourceEvent * event) {
-  XmedDataModel * dataModel = (XmedDataModel *)this->getDataModel();
+void WorkspaceController::processDatasourceEvent(const DatasourceEvent* event) {
+  XmedDataModel* dataModel = (XmedDataModel*)this->getDataModel();
   if ( dataModel == NULL ) {
     STDLOG("No data model associated to this tree view");
     return;
@@ -471,9 +531,10 @@ void WorkspaceController::processDatasourceEvent(const DatasourceEvent * event)
   // options such that "change the underlying mesh".
   // <<<
 
-  XmedDataObject * dataObject = event->objectdata;
+  XmedDataObject* dataObject = event->objectdata;
 
   if ( event->eventtype == DatasourceEvent::EVENT_IMPORT_OBJECT ) {
+    std::cout << "IMPORT object in workspace: " << dataObject->toString() << std::endl;
     STDLOG("IMPORT object in workspace:\n"<<dataObject->toString());
     // _GBO_ QUESTION: tag automatically the object as a peristant object ??
     // We first add the data object to the internal data model
@@ -495,31 +556,58 @@ void WorkspaceController::processDatasourceEvent(const DatasourceEvent * event)
           askForOptions,
           QCHARSTAR(event->objectalias));
   }
-  else if ( event->eventtype == DatasourceEvent::EVENT_VIEW_OBJECT_SCALAR_MAP ) {
-    QStringList commands;
-
-#define stringify( name ) # name
-    QString viewMode = stringify(MEDCALC::VIEW_MODE_NEW_LAYOUT); // :TODO: change this (get value from dedicated dialog)
-    viewMode.replace("::", ".");
-
-    MEDCALC::FieldHandler* fieldHandler = dataObject->getFieldHandler();
-    commands += QString("medcalc.MakeScalarMap(accessField(%1), %2)").arg(fieldHandler->id).arg(viewMode);
-    _consoleDriver->exec(commands);
-  }
   else if ( event->eventtype == DatasourceEvent::EVENT_ADD_DATASOURCE ) {
     QStringList commands;
-    commands += QString("medcalc.LoadDataSource('%1')").arg(event->objectalias);
+    commands += QString("source_id = medcalc.LoadDataSource('%1')").arg(event->objectalias);
+    commands += QString("source_id");
     _consoleDriver->exec(commands);
+
+    // Create a default presentation when loading a file
+    MEDCALC::MedEvent* evt = new MEDCALC::MedEvent();
+    evt->type = MEDCALC::EVENT_ADD_PRESENTATION;
+    evt->dataId = -1;
+    emit workspaceSignal(evt); // forward to PresentationController
   }
   else if ( event->eventtype == DatasourceEvent::EVENT_ADD_IMAGE_AS_DATASOURCE ) {
     QStringList commands;
-    commands += QString("medcalc.LoadImageAsDataSource('%1')").arg(event->objectalias);
+    commands += QString("source_id = medcalc.LoadImageAsDataSource('%1')").arg(event->objectalias);
+    commands += QString("source_id");
     _consoleDriver->exec(commands);
   }
   else {
     STDLOG("The event "<<event->eventtype<<" is not implemented yet");
   }
+}
+
+void
+WorkspaceController::processProcessingEvent(const ProcessingEvent* event)
+{
+  XmedDataModel* dataModel = (XmedDataModel*)this->getDataModel();
+  if ( dataModel == NULL ) {
+    STDLOG("No data model associated to this tree view");
+    return;
+  }
+
+  int fieldId = event->fieldId;
+  int meshId = event->meshId;
+
+  if ( event->eventtype == ProcessingEvent::EVENT_CHANGE_UNDERLYING_MESH ) {
+    QStringList commands;
+    commands += QString("result_id = medcalc.ChangeUnderlyingMesh(fieldId=%1,meshId=%2)").arg(fieldId).arg(meshId);
+    commands += QString("result_id");
+    _consoleDriver->exec(commands);
+  }
+  else if ( event->eventtype == ProcessingEvent::EVENT_INTERPOLATE_FIELD ) {
+    MEDCALC::InterpolationParameters params = event->interpParams;
+    QString method = QString(params.method);
+    QString nature = QString(params.nature);
+    QString intersectionType = QString(params.intersectionType);
 
+    QStringList commands;
+    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);
+    commands += QString("result_id");
+    _consoleDriver->exec(commands);
+  }
 }
 
 void WorkspaceController::OnSaveWorkspace() {