Salome HOME
Typo-fix by Kunda
[modules/med.git] / src / MEDCalc / gui / MEDModule.cxx
1 // Copyright (C) 2007-2020  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 "MEDModule.hxx"
23 #include "QtHelper.hxx"
24 #include <MEDCalcConstants.hxx>
25
26 #include "SALOME_LifeCycleCORBA.hxx"
27 #include "QtxPopupMgr.h"
28
29 #include <LightApp_Preferences.h>
30 #include <SUIT_Desktop.h>
31 #include <SUIT_ResourceMgr.h>
32 #include <SUIT_Session.h>
33 #include <SUIT_DataBrowser.h>
34 #include <SalomeApp_Study.h>
35 #include <SalomeApp_DataObject.h>
36 #include <SalomeApp_DataModel.h>
37
38 #include <SALOMEconfig.h>
39 #include CORBA_CLIENT_HEADER(SALOMEDS_Attributes)
40 #include <SALOMEDS_SObject.hxx>
41 #include <SALOMEDS_Study.hxx>
42
43 #ifndef DISABLE_PVVIEWER
44 #include <PVViewer_ViewModel.h>
45 #include <PVViewer_GUIElements.h>
46 #endif
47
48 #include "MEDFactoryClient.hxx"
49 #include "MEDPresentationManager_i.hxx"
50
51 #include <QTimer>
52 #include <sstream>
53
54 #include <pqAnimationManager.h>
55 #include <pqPVApplicationCore.h>
56 #include <pqAnimationScene.h>
57
58 //! The only instance of the reference to engine
59 MED_ORB::MED_Gen_var MEDModule::_MED_engine;
60
61 MEDModule::MEDModule() :
62   SalomeApp_Module("FIELDS"), _studyEditor(0),
63   _datasourceController(0), _workspaceController(0), _presentationController(0),
64   _processingController(0), _pvGuiElements(0)
65 {
66   STDLOG("MEDModule::MEDModule()");
67   // Note also that we can't use the getApp() function here because
68   // the initialize(...) function has not been called yet.
69
70   init(); // internal initialization
71 }
72
73 MEDModule::~MEDModule()
74 {
75   // Clean up engine:
76   STDLOG("MEDModule::~MEDModule(): cleaning up engine side.");
77   _MED_engine->cleanUp();
78   MEDFactoryClient::getFactory()->getPresentationManager()->cleanUp();
79   MEDFactoryClient::getFactory()->getDataManager()->cleanUp();
80
81   if (_studyEditor)
82     delete _studyEditor;
83   if (_datasourceController)
84     delete _datasourceController;
85   //if (_workspaceController)
86   //  delete _workspaceController;
87   if (_presentationController)
88     delete _presentationController;
89   if (_processingController)
90     delete _processingController;
91 }
92
93 MED_ORB::MED_Gen_var
94 MEDModule::engine()
95 {
96   init(); // initialize engine, if necessary
97   return _MED_engine;
98 }
99
100 void
101 MEDModule::init()
102 {
103   // initialize FIELDS module engine (load, if necessary)
104   if ( CORBA::is_nil( _MED_engine ) ) {
105     Engines::EngineComponent_var comp =
106       SalomeApp_Application::lcc()->FindOrLoad_Component( "FactoryServer", "FIELDS" );
107     if (CORBA::is_nil( comp )) {
108       STDLOG("Could not FindOrLoad_Component FIELDS");
109     }
110     _MED_engine = MED_ORB::MED_Gen::_narrow( comp );
111     if (CORBA::is_nil( _MED_engine )) {
112       STDLOG("Could not narrow FIELDS engine");
113     }
114   }
115 }
116
117 //void MEDModule::onEventLoopStarted()
118 //{
119 //  if(!getApp()->isMainEventLoopStarted())
120 //    {
121 //      QTimer::singleShot(100, this, SLOT(onEventLoopStarted()));
122 //      return;
123 //    }
124 //}
125
126 void
127 MEDModule::initialize( CAM_Application* app )
128 {
129   STDLOG("MEDModule::initialize()");
130   // call the parent implementation
131   SalomeApp_Module::initialize( app );
132
133   if (! getApp()->objectBrowser())
134     getApp()->getWindow(SalomeApp_Application::WT_ObjectBrowser);
135
136   getApp()->objectBrowser()->setAutoOpenLevel(5);
137
138   if (app && app->desktop()) {
139     connect((QObject*) (getApp()->objectBrowser()->treeView()), SIGNAL(doubleClicked(const QModelIndex&)),
140             this, SLOT(onDblClick(const QModelIndex&)));
141     connect((QObject*) (getApp()->objectBrowser()->treeView()), SIGNAL(clicked(const QModelIndex&)),
142                 this, SLOT(onClick(const QModelIndex&)));
143   }
144
145   // The following initializes the GUI widget and associated actions
146   this->createModuleWidgets();
147   this->createModuleActions();
148
149   // Now that the workspace controller is created, ParaView core application has normally been started,
150   // and hidden GUI elements have been created.  We can fire the VCR toolbar activation:
151   initToolbars();
152 }
153
154 QString
155 MEDModule::engineIOR() const
156 {
157   init(); // initialize engine, if necessary
158   CORBA::String_var anIOR = getApp()->orb()->object_to_string( _MED_engine.in() );
159   return QString( anIOR.in() );
160 }
161
162 QString
163 MEDModule::iconName() const
164 {
165   return tr("ICO_MED_SMALL");
166 }
167
168 void
169 MEDModule::windows( QMap<int, int>& theMap ) const
170 {
171   STDLOG("MEDModule::windows()");
172   // want Object browser, in the left area
173   theMap.insert( SalomeApp_Application::WT_ObjectBrowser,
174                  Qt::LeftDockWidgetArea );
175 #ifndef DISABLE_PYCONSOLE
176   // want Python console, in the bottom area
177   theMap.insert( SalomeApp_Application::WT_PyConsole,
178                  Qt::BottomDockWidgetArea );
179 #endif
180 }
181
182 void
183 MEDModule::viewManagers( QStringList& list ) const
184 {
185 #ifndef DISABLE_PVVIEWER
186   list.append( PVViewer_Viewer::Type() );
187 #endif
188 }
189
190 void
191 MEDModule::createPreferences()
192 {
193   int genTab = addPreference(tr("PREF_TAB_GENERAL"));
194
195   int themeGroup = addPreference(tr("PREF_THEME_GROUP"), genTab);
196   setPreferenceProperty(themeGroup, "columns", 2);
197   int icons = addPreference(tr("PREF_ICONS"), themeGroup, LightApp_Preferences::Selector, "MEDCalc", "icons" );
198   QStringList iconsThemes;
199   iconsThemes.append(tr("PREF_ICON_THEME_MODERN"));
200   iconsThemes.append(tr("PREF_ICON_THEME_CLASSIC"));
201   QList<QVariant> indices;
202   indices.append(0);
203   indices.append(1);
204   setPreferenceProperty(icons, "strings", iconsThemes);
205   setPreferenceProperty(icons, "indexes", indices);
206 }
207
208 bool
209 MEDModule::activateModule( SUIT_Study* theStudy )
210 {
211   STDLOG("MEDModule::activateModule()");
212   if ( CORBA::is_nil( _MED_engine ) )
213     return false;
214
215   // call parent implementation
216   bool bOk = SalomeApp_Module::activateModule( theStudy );
217   if (!bOk)
218     return false;
219
220   // show own menus
221   setMenuShown( true );
222   // show own toolbars
223   setToolShown( true );
224
225   //this->createStudyComponent(theStudy);
226   _workspaceController->showDockWidgets(true);
227   _presentationController->showDockWidgets(true);
228   //this->setDockLayout(StandardApp_Module::DOCKLAYOUT_LEFT_VLARGE);
229
230   // Mark the start of the main event loop - important for test playback:
231 //  QObject::connect(getApp(), SIGNAL(activated(SUIT_Application *)), this, SLOT(onEventLoopStarted(SUIT_Application *)));
232 //  QTimer::singleShot(0, this, SLOT(onEventLoopStarted()));
233
234   // return the activation status
235   return bOk;
236 }
237
238 bool
239 MEDModule::deactivateModule( SUIT_Study* theStudy )
240 {
241   STDLOG("MEDModule::deactivateModule()");
242   _workspaceController->showDockWidgets(false);
243   _presentationController->showDockWidgets(false);
244   //this->unsetDockLayout();
245
246   // hide own menus
247   setMenuShown( false );
248   // hide own toolbars
249   setToolShown( false );
250
251   // call parent implementation and return the activation status
252   return SalomeApp_Module::deactivateModule( theStudy );
253 }
254
255 //
256 // =====================================================================
257 // This part add custom widgets (a dockwidget containing a tree view
258 // in this example) and add special actions in the toolbox of the
259 // module.
260 // =====================================================================
261 //
262
263 /*!
264  * This function implements the interface StandardApp_Module. It
265  * creates the widgets specific for this module, in particular the
266  * workspace widget and the dataspace widget.
267  */
268 void
269 MEDModule::createModuleWidgets() {
270   _studyEditor = new SALOME_AppStudyEditor(getApp());
271   _datasourceController = new DatasourceController(this);
272   _workspaceController = new WorkspaceController(this);
273   _xmedDataModel  = new XmedDataModel();
274   _workspaceController->setDataModel(_xmedDataModel);
275   _presentationController = new PresentationController(this);
276   // ABN: ultimately console driver should be owned by module: everyone needs it, not only WorkspaceController
277   _presentationController->setConsoleDriver(_workspaceController->getConsoleDriver());
278   _processingController = new ProcessingController(this);
279 #ifdef MED_HAS_QTTESTING
280   _testController = new TestController(this);
281 #endif
282
283   connect(_datasourceController, SIGNAL(datasourceSignal(const DatasourceEvent*)),
284     _workspaceController, SLOT(processDatasourceEvent(const DatasourceEvent*)));
285
286   connect(_presentationController, SIGNAL(presentationSignal(const PresentationEvent*)),
287     _presentationController, SLOT(processPresentationEvent(const PresentationEvent*)));
288
289   connect(_processingController, SIGNAL(processingSignal(const ProcessingEvent*)),
290     _workspaceController, SLOT(processProcessingEvent(const ProcessingEvent*)));
291
292   connect(_workspaceController, SIGNAL(workspaceSignal(const MEDCALC::MedEvent*)),
293     _datasourceController, SLOT(processWorkspaceEvent(const MEDCALC::MedEvent*)));
294
295   connect(_workspaceController, SIGNAL(workspaceSignal(const MEDCALC::MedEvent*)),
296     _presentationController, SLOT(processWorkspaceEvent(const MEDCALC::MedEvent*)));
297 }
298
299 void
300 MEDModule::initToolbars()
301 {
302   // VCR and Time toolbars:
303   SUIT_Desktop* dsk = getApp()->desktop();
304   _pvGuiElements = PVViewer_GUIElements::GetInstance(dsk);
305
306   _pvGuiElements->getVCRToolbar();  // make sure VCR toolbar is built
307   _pvGuiElements->setToolBarVisible(false);
308   _pvGuiElements->setVCRTimeToolBarVisible(true);
309
310   // Emit signal in order to make sure that animation scene is set - same trick as in PARAVIS module activation
311   QMetaObject::invokeMethod( pqPVApplicationCore::instance()->animationManager(),
312                              "activeSceneChanged",
313                              Q_ARG( pqAnimationScene*, pqPVApplicationCore::instance()->animationManager()->getActiveScene() ) );
314
315 #ifdef MED_HAS_QTTESTING
316   connect(_workspaceController, SIGNAL(workspaceSignal(const MEDCALC::MedEvent*)),
317     _testController, SLOT(processWorkspaceEvent(const MEDCALC::MedEvent*)));
318 #endif
319 }
320
321 double
322 MEDModule::getCurrentAnimationTimestamp()
323 {
324   double timestamp = pqPVApplicationCore::instance()->animationManager()->getActiveScene()->getAnimationTime();
325   return timestamp;
326 }
327
328 void
329 MEDModule::createModuleActions() {
330   _datasourceController->createActions();
331   _workspaceController->createActions();
332   _presentationController->createActions();
333   _processingController->createActions();
334 #ifdef MED_HAS_QTTESTING
335   _testController->createActions();
336 #endif
337 }
338
339 int
340 MEDModule::createStandardAction(const QString& label,
341                                 QObject* slotobject,
342                                 const char* slotmember,
343                                 const QString& iconName,
344                                 const QString& tooltip)
345 {
346   SUIT_Desktop* dsk = getApp()->desktop();
347   SUIT_ResourceMgr* resMgr = getApp()->resourceMgr();
348
349   // If the tooltip is not defined, we choose instead the label text.
350   QString effToolTip(tooltip);
351   if ( effToolTip.isEmpty() )
352     effToolTip = label;
353
354   QIcon ico;
355   if (iconName.isEmpty())
356     ico = QIcon();
357   else
358     ico = QIcon(resMgr->loadPixmap("FIELDS", iconName));
359
360   QAction* action = createAction(-1,
361                                  label,
362                                  ico,
363                                  label,
364                                  effToolTip,
365                                  0,
366                                  dsk,
367                                  false,
368                                  slotobject,
369                                  slotmember
370                                  );
371   return actionId(action);
372 }
373
374 void
375 MEDModule::addActionInPopupMenu(int actionId,const QString& menus,const QString& rule)
376 {
377   // _GBO_ for a fine customization of the rule (for example with a
378   // test on the type of the selected object), see the LIGHT module:
379   // implement "LightApp_Selection*    createSelection() const;"
380   int parentId = -1;
381   QtxPopupMgr* mgr = this->popupMgr();
382   this->action( actionId )->setIconVisibleInMenu(true);
383   if (! menus.isEmpty())
384     mgr->insert ( this->action( actionId ), menus, parentId, 0 );
385   else
386     mgr->insert ( this->action( actionId ), parentId, 0 );
387   mgr->setRule( this->action( actionId ), rule, QtxPopupMgr::VisibleRule );
388 }
389
390 //MEDCALC::ViewModeType
391 //MEDModule::getSelectedViewMode() const
392 //{
393 //  return _presentationController->getSelectedViewMode();
394 //}
395 //
396 //MEDCALC::ColorMapType
397 //MEDModule::getSelectedColorMap() const
398 //{
399 //  return _presentationController->getSelectedColorMap();
400 //}
401 //
402 //MEDCALC::ScalarBarRangeType
403 //MEDModule::getSelectedScalarBarRange() const
404 //{
405 //  return _presentationController->getSelectedScalarBarRange();
406 //}
407
408
409 /**
410  * Returns presentation name, type and ID from the currently selected presentation in the object
411  * browser.
412  */
413 bool
414 MEDModule::itemClickGeneric(std::string & name, std::string & type, int & presId) const
415 {
416   DataObjectList dol = getApp()->objectBrowser()->getSelected();
417   if (dol.isEmpty())
418     return false;
419   SalomeApp_DataObject* item = dynamic_cast<SalomeApp_DataObject*>(dol[0]);
420   if (!item)
421     return false;
422   SalomeApp_DataModel *model = dynamic_cast<SalomeApp_DataModel*>(dataModel());
423   if (!model)
424     return false;
425
426   if (item->componentDataType().toStdString() != "FIELDS")
427     return false;
428   _PTR(SObject) obj = item->object();
429   _PTR(GenericAttribute) anAttribute;
430
431   if (! obj->FindAttribute(anAttribute, "AttributeName"))
432     return false;
433   _PTR(AttributeName) attrName(anAttribute);
434   name = attrName->Value();
435
436   if (! obj->FindAttribute(anAttribute, "AttributeParameter"))
437     return false;
438   _PTR(AttributeParameter) attrParam(anAttribute);
439   if (! attrParam->IsSet(IS_PRESENTATION, PT_BOOLEAN)
440       || ! attrParam->GetBool(IS_PRESENTATION)) { // Not a presentation
441       return false;
442   }
443 //  if (!attrParam->IsSet(FIELD_ID, PT_INTEGER))
444 //    return false;
445 //  fieldId = attrParam->GetInt(FIELD_ID);
446   if (!attrParam->IsSet(PRESENTATION_ID, PT_INTEGER))
447       return false;
448   presId = attrParam->GetInt(PRESENTATION_ID);
449   if (!attrParam->IsSet(PRESENTATION_TYPE, PT_STRING))
450     return false;
451   type = attrParam->GetString(PRESENTATION_TYPE);
452   return true;
453 }
454
455 void
456 MEDModule::onClick(const QModelIndex & /*index*/)
457 {
458   int presId;
459   std::string name, type;
460   if (!itemClickGeneric(name, type, presId))
461     {
462       // Not a presentation - clear widget:
463       emit presentationSelected(-1, QString(""), QString(""));
464       return;
465     }
466
467 //  STDLOG("Presentation selection");
468 //  std::ostringstream oss;
469 //  oss << fieldId << " / " << presId;
470 //  STDLOG("    - Field id / pres id:   " + oss.str());
471 //  STDLOG("    - Presentation type: " + type);
472 //  STDLOG("    - Presentation name: " + name);
473
474   emit presentationSelected(presId, QString::fromStdString(type), QString::fromStdString(name) );  // caught by PresentationController
475 }
476
477 void
478 MEDModule::onDblClick(const QModelIndex& /*index*/)
479 {
480   int presId;
481   std::string name, type;
482   if (!itemClickGeneric(name, type, presId))
483     return;
484
485 //  STDLOG("Presentation double click");
486 //  STDLOG("  Presentation infos:");
487 //  STDLOG("    - Component:         " + item->componentDataType().toStdString());
488 //  STDLOG("    - Item entry:        " + item->entry().toStdString());
489 //  STDLOG("    - Item name:         " + item->name().toStdString());
490 //  std::ostringstream oss;
491 //  oss << fieldId;
492 //  STDLOG("    - Field id:          " + oss.str());
493 //  STDLOG("    - Presentation name: " + name);
494 }
495
496 void
497 MEDModule::requestSALOMETermination() const
498 {
499   STDLOG("Requesting SALOME termination!!");
500   SUIT_Session::session()->closeSession( SUIT_Session::DONT_SAVE, 1 );  // killServers = True
501 }
502
503
504 //bool MEDModule::hasMainEventLoopStarted() const
505 //{
506 //  return _eventLoopStarted;
507 //}
508
509 int
510 MEDModule::getIntParamFromStudyEditor(SALOMEDS::SObject_var obj, const char* name)
511 {
512   if (obj->_is_nil())
513     return -1;
514
515   SALOMEDS::GenericAttribute_var anAttr;
516   SALOMEDS::AttributeParameter_var aParam;
517   if ( obj->FindAttribute(anAttr,"AttributeParameter") ) {
518     aParam = SALOMEDS::AttributeParameter::_narrow(anAttr);
519     if (aParam->IsSet(name, PT_INTEGER))
520       return aParam->GetInt(name);
521   }
522   return -1;
523 }