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