1 // Copyright (C) 2007-2016 CEA/DEN, EDF R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 // Author : Guillaume Boulant (EDF)
22 #include "DatasourceController.hxx"
23 #include <MEDCalcConstants.hxx>
25 #include <SalomeApp_Application.h>
26 #include <SalomeApp_Study.h>
27 #include <SalomeApp_DataObject.h>
29 #include <SALOME_ListIO.hxx>
30 #include <LightApp_SelectionMgr.h>
32 #include <SALOME_LifeCycleCORBA.hxx>
33 #include <SALOMEDS_SObject.hxx>
34 #include <SALOMEDS_Study.hxx>
36 #include "MEDFactoryClient.hxx"
37 #include "MEDModule.hxx"
38 #include "QtHelper.hxx"
40 #include CORBA_CLIENT_HEADER(SALOMEDS)
41 #include CORBA_CLIENT_HEADER(SALOMEDS_Attributes)
42 #include <SUIT_FileDlg.h>
43 #include <SUIT_Desktop.h>
45 #include <QStringList>
47 #include <QMessageBox>
49 #include "DlgAlias.hxx"
52 // ==============================================================
53 // Datasource controller
54 // ==============================================================
56 DatasourceController::DatasourceController(MEDModule* salomeModule)
58 STDLOG("Creating a DatasourceController");
59 _salomeModule = salomeModule;
60 _studyEditor = _salomeModule->getStudyEditor();
63 DatasourceController::~DatasourceController() {
64 STDLOG("Deleting the DatasourceController");
67 void DatasourceController::createActions() {
68 int toolbarId = _salomeModule->createTool("Datasource", "DatasourceToolbar");
71 // Main actions (toolbar and menubar)
73 QString label = tr("LAB_ADD_DATA_SOURCE");
74 QString tooltip = tr("TIP_ADD_DATA_SOURCE");
75 QString icon = tr("ICO_DATASOURCE_ADD");
77 actionId = _salomeModule->createStandardAction(label,this, SLOT(OnAddDatasource()),icon,tooltip);
78 _salomeModule->createTool(actionId, toolbarId);
80 // This action has to be placed in the general file menu with the label "Import MED file"
81 int menuId = _salomeModule->createMenu( tr( "MEN_FILE" ), -1, 1 );
82 _salomeModule->action(actionId)->setIconVisibleInMenu(true);
83 _salomeModule->createMenu(actionId, menuId, 10);
85 label = tr("LAB_ADD_IMAGE_SOURCE");
86 tooltip = tr("TIP_ADD_IMAGE_SOURCE");
87 icon = tr("ICO_IMAGE_ADD");
88 actionId = _salomeModule->createStandardAction(label,this, SLOT(OnAddImagesource()),icon,tooltip);
89 _salomeModule->createTool(actionId, toolbarId);
90 _salomeModule->action(actionId)->setIconVisibleInMenu(true);
91 _salomeModule->createMenu(actionId, menuId, 20);
94 // Actions for popup menu only
96 // Expand field timeseries
97 label = tr("LAB_EXPAND_FIELD");
98 icon = tr("ICO_DATASOURCE_EXPAND_FIELD");
99 actionId = _salomeModule->createStandardAction(label,this,SLOT(OnExpandField()),icon);
100 _salomeModule->addActionInPopupMenu(actionId);
103 label = tr("LAB_USE_IN_WORKSPACE");
104 icon = tr("ICO_DATASOURCE_USE");
105 actionId = _salomeModule->createStandardAction(label,this,SLOT(OnUseInWorkspace()),icon);
106 _salomeModule->addActionInPopupMenu(actionId);
110 * This function adds the specified MED file as a datasource in the
111 * dataspace. Technically speaking, the engine loads the
112 * meta-information concerning med data from the file, gives this
113 * informations to the GUI, and the GUI creates a tree view of these
114 * data in the study object browser.
116 // This function emits a signal that will be caught by workspace to delegate command (datasource creation) to python console.
118 DatasourceController::addDatasource(const char* filename)
120 DatasourceEvent* event = new DatasourceEvent();
121 event->eventtype = DatasourceEvent::EVENT_ADD_DATASOURCE;
122 event->objectalias = filename;
123 emit datasourceSignal(event);
125 // After above data source creation, python console emits a signal, forwarded by workspace, to update the GUI
127 DatasourceController::updateTreeViewWithNewDatasource(const MEDCALC::DatasourceHandler* datasourceHandler)
129 if (!datasourceHandler) {
133 SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>(_salomeModule->application()->activeStudy());
134 _PTR(Study) studyDS = study->studyDS();
136 _salomeModule->engine()->addDatasourceToStudy(_CAST(Study, studyDS)->GetStudy(), *datasourceHandler);
138 // update Object browser
139 _salomeModule->getApp()->updateObjectBrowser(true);
142 void DatasourceController::OnAddDatasource()
144 // Dialog to get the filename where the input data are read from
146 filter.append(tr("FILE_FILTER_MED"));
148 QString anInitialPath = "";
149 if ( SUIT_FileDlg::getLastVisitedPath().isEmpty() )
150 anInitialPath = QDir::currentPath();
152 QStringList filenames = SUIT_FileDlg::getOpenFileNames( _salomeModule->getApp()->desktop(),
155 tr("IMPORT_MED_FIELDS") );
157 if ( filenames.count() <= 0 ) return;
158 for ( QStringList::ConstIterator itFile = filenames.begin();
159 itFile != filenames.end(); ++itFile ) {
160 QString filename = *itFile;
161 this->addDatasource(QCHARSTAR(filename));
162 _salomeModule->updateObjBrowser(true);
166 #include "DlgImageToMed.hxx"
167 void DatasourceController::OnAddImagesource()
170 DlgImageToMed dialog;
171 dialog.setAutoLoaded(true);
172 int choice = dialog.exec();
173 if ( choice == QDialog::Rejected ) {
174 // The user decides to cancel the operation
178 QString imageFilename = dialog.getImageFilepath();
180 QString medFilename = dialog.getMedFilepath();
181 bool autoLoad = dialog.isAutoLoaded();
183 std::string ROOT_DIR(getenv("MED_ROOT_DIR"));
184 std::string command(ROOT_DIR+"/bin/salome/med/image2med.py");
185 command += " -i "+QS2S(imageFilename);
186 command += " -m "+QS2S(medFilename);
187 int error = system(command.c_str());
189 QMessageBox::critical(_salomeModule->getApp()->desktop(),
190 tr("Operation failed"),
191 tr("The creation of med data from the image file failed"));
196 this->addDatasource(QCHARSTAR(medFilename));
197 _salomeModule->updateObjBrowser(true);
201 DatasourceEvent* event = new DatasourceEvent();
202 event->eventtype = DatasourceEvent::EVENT_ADD_IMAGE_AS_DATASOURCE;
203 event->objectalias = imageFilename;
204 emit datasourceSignal(event);
207 void DatasourceController::OnExpandField()
209 // We need a studyEditor updated on the active study
210 _studyEditor->updateActiveStudy();
212 // Get the selected objects in the study (SObject)
213 SALOME_StudyEditor::SObjectList* listOfSObject = _studyEditor->getSelectedObjects();
214 for (int i=0; i<listOfSObject->size(); i++) {
215 SALOMEDS::SObject_var soFieldseries = listOfSObject->at(i);
217 // First retrieve the fieldseries id associated to this study object
218 //long fieldseriesId = _studyEditor->getParameterInt(soFieldseries,FIELD_SERIES_ID);
219 long fieldseriesId = _studyEditor->getParameterInt(soFieldseries,FIELD_ID);
220 STDLOG("Expand the field timeseries "<<fieldseriesId);
222 // If fieldseriesId equals -1, then it means that it is not a
223 // fieldseries managed by the MED module, and we stop this
225 if ( fieldseriesId < 0 )
227 // _GBO_ A better correction should be to no display the
228 // contextual menu if the selected object is not conform
230 // Then retrieve the list of fields in this timeseries
231 MEDCALC::FieldHandlerList* fieldHandlerList =
232 MEDFactoryClient::getDataManager()->getFieldListInFieldseries(fieldseriesId);
234 // Finally, create an entry for each of the field
235 for(CORBA::ULong iField=0; iField<fieldHandlerList->length(); iField++) {
236 MEDCALC::FieldHandler fieldHandler = (*fieldHandlerList)[iField];
237 SALOMEDS::SObject_var soField = _studyEditor->newObject(soFieldseries);
238 std::string label("it="); label += ToString(fieldHandler.iteration);
239 _studyEditor->setName(soField,label.c_str());
240 _studyEditor->setParameterInt(soField, FIELD_ID, fieldHandler.id);
241 _studyEditor->setParameterBool(soField,IS_IN_WORKSPACE,false);
244 _salomeModule->updateObjBrowser(true);
247 void DatasourceController::OnUseInWorkspace() {
248 // We need a studyEditor updated on the active study
249 _studyEditor->updateActiveStudy();
251 // Get the selected objects in the study (SObject)
252 SALOME_StudyEditor::SObjectList* listOfSObject = _studyEditor->getSelectedObjects();
253 if ( listOfSObject->size() == 1 ) {
254 // In this case we ask the name of the variable for the python
258 // _GBO_ Note that it works only for a single field but the
259 // XmedDataObject will be improved to deal with mesh, timeseries
260 // and single field in a futur version. We suppose here that a
261 // single field has been selected.
264 SALOMEDS::SObject_var soField = listOfSObject->at(0);
266 bool isInWorkspace = _studyEditor->getParameterBool(soField,IS_IN_WORKSPACE);
267 if ( isInWorkspace ) {
268 QMessageBox::warning(_salomeModule->getApp()->desktop(),
269 tr("Operation not allowed"),
270 tr("This field is already defined in the workspace"));
274 int fieldId = _studyEditor->getParameterInt(soField,FIELD_ID);
276 // If fieldId equals -1, then it means that it is not a field
277 // managed by the MED module, and we stop this function process.
279 QMessageBox::warning(_salomeModule->getApp()->desktop(),
280 tr("Operation not allowed"),
281 tr("This element is not a field object"));
285 MEDCALC::FieldHandler* fieldHandler =
286 MEDFactoryClient::getDataManager()->getFieldHandler(fieldId);
288 if (! fieldHandler) {
289 QMessageBox::warning(_salomeModule->getApp()->desktop(),
290 tr("Operation not allowed"),
291 tr("No field is defined"));
295 QString alias(fieldHandler->fieldname);
297 dialog.setAlias(alias);
298 int choice = dialog.exec();
299 if ( choice == QDialog::Rejected ) {
300 // The user decides to cancel the operation
303 alias = dialog.getAlias();
305 DatasourceEvent* event = new DatasourceEvent();
306 event->eventtype = DatasourceEvent::EVENT_USE_OBJECT;
307 XmedDataObject* dataObject = new XmedDataObject();
308 dataObject->setFieldHandler(*fieldHandler);
309 event->objectdata = dataObject;
310 event->objectalias = alias;
311 emit datasourceSignal(event);
312 // Tag the item to prevent double import
313 // _studyEditor->setParameterBool(soField,IS_IN_WORKSPACE,true);
314 // Tag the field as persistent on the server. It means that a
315 // saving of the workspace will save at least this field (maybe it
316 // should be an option?)
317 MEDFactoryClient::getDataManager()->markAsPersistent(fieldId, true);
320 // In this case, we don't ask the user to specify an alias for
321 // each item, we just import the whole set of items.
322 for (int i=0; i<listOfSObject->size(); i++) {
323 SALOMEDS::SObject_var soField = listOfSObject->at(i);
325 bool isInWorkspace = _studyEditor->getParameterBool(soField,IS_IN_WORKSPACE);
326 if ( !isInWorkspace ) {
327 int fieldId = _studyEditor->getParameterInt(soField,FIELD_ID);
328 MEDCALC::FieldHandler* fieldHandler =
329 MEDFactoryClient::getDataManager()->getFieldHandler(fieldId);
330 DatasourceEvent* event = new DatasourceEvent();
331 event->eventtype = DatasourceEvent::EVENT_IMPORT_OBJECT;
332 XmedDataObject* dataObject = new XmedDataObject();
333 dataObject->setFieldHandler(*fieldHandler);
334 event->objectdata = dataObject;
335 emit datasourceSignal(event);
336 // Note that this signal is processed by the WorkspaceController
338 // Tag the item to prevent double import
339 // _studyEditor->setParameterBool(soField,IS_IN_WORKSPACE,true);
340 // Tag the field as persistent on the server. It means that a
341 // saving of the workspace will save at least this field (maybe it
342 // should be an option?)
343 MEDFactoryClient::getDataManager()->markAsPersistent(fieldId, true);
346 STDLOG("The field "<<_studyEditor->getName(soField)<<
347 " is already defined in the workspace");
354 DatasourceController::processWorkspaceEvent(const MEDCALC::MedEvent* event)
356 if ( event->type == MEDCALC::EVENT_ADD_DATASOURCE ) {
357 MEDCALC::DatasourceHandler* datasourceHandler = MEDFactoryClient::getDataManager()->getDatasourceHandler(event->filename);
358 this->updateTreeViewWithNewDatasource(datasourceHandler);