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