]> SALOME platform Git repositories - modules/paravis.git/blob - src/PVGUI/PVGUI_Module.cxx
Salome HOME
Merge branch 'V8_5_BR' of https://codev-tuleap.cea.fr/plugins/git/salome/paravis...
[modules/paravis.git] / src / PVGUI / PVGUI_Module.cxx
1 // PARAVIS : ParaView wrapper SALOME module
2 //
3 // Copyright (C) 2010-2016  CEA/DEN, EDF R&D
4 //
5 // This library is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU Lesser General Public
7 // License as published by the Free Software Foundation; either
8 // version 2.1 of the License, or (at your option) any later version.
9 //
10 // This library is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 // Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public
16 // License along with this library; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
18 //
19 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 //
21 // File   : PVGUI_Module.cxx
22
23 #define PARAVIS_MODULE_NAME "PARAVIS"
24
25 #include <Standard_math.hxx>  // E.A. must be included before Python.h to fix compilation on windows
26 #ifdef HAVE_FINITE
27 #undef HAVE_FINITE            // VSR: avoid compilation warning on Linux : "HAVE_FINITE" redefined
28 #endif
29 #include <vtkPython.h> // Python first
30
31 #include "PVGUI_Module.h"
32
33 #include "PVViewer_ViewManager.h"
34 #include "PVViewer_Core.h"
35 #include "PVViewer_ViewWindow.h"
36 #include "PVViewer_ViewModel.h"
37 #include "PVGUI_ParaViewSettingsPane.h"
38 #include "PVViewer_GUIElements.h"
39 #include "PVServer_ServiceWrapper.h"
40 #include "PVGUI_DataModel.h"
41
42 // SALOME Includes
43 #include <utilities.h>
44 #include <SUIT_DataBrowser.h>
45 #include <SUIT_Desktop.h>
46 #include <SUIT_MessageBox.h>
47 #include <SUIT_ResourceMgr.h>
48 #include <SUIT_Session.h>
49 #include <SUIT_OverrideCursor.h>
50 #include <SUIT_ExceptionHandler.h>
51
52 #include <LightApp_SelectionMgr.h>
53 #include <LightApp_NameDlg.h>
54 #include <LightApp_Application.h>
55 #include <LightApp_Study.h>
56 #include <SALOME_ListIO.hxx>
57
58 #include <QtxActionMenuMgr.h>
59 #include <QtxActionToolMgr.h>
60
61 #include <PARAVIS_version.h>
62
63 // External includes
64 #include <sstream>
65
66 #include <QAction>
67 #include <QApplication>
68 #include <QCursor>
69 #include <QDir>
70 #include <QFile>
71 #include <QFileInfo>
72 #include <QIcon>
73 #include <QInputDialog>
74 #include <QMenu>
75 #include <QStatusBar>
76 #include <QString>
77 #include <QStringList>
78 #include <QTimer>
79 #include <QToolBar>
80 #include <QTextStream>
81 #include <QShortcut>
82 #include <QDockWidget>
83 #include <QHelpEngine>
84
85 // Paraview includes
86 #include <vtkPVConfig.h>  // for symbol PARAVIEW_VERSION
87 #include <vtkProcessModule.h>
88 #include <vtkPVSession.h>
89 #include <vtkPVProgressHandler.h>
90 #include <vtkOutputWindow.h>
91 #include <vtkEventQtSlotConnect.h>
92 #include <vtkNew.h>
93 #include <vtkSMProxy.h>
94 #include <vtkSmartPointer.h>
95 #include <vtkSMSession.h>
96 #include <vtkSMTrace.h>
97 #include <vtkSMSessionProxyManager.h>
98 #include <vtkSMParaViewPipelineController.h>
99 #include <vtkSmartPyObject.h>
100
101 #include <pqApplicationCore.h>
102 #include <pqPVApplicationCore.h>
103 #include <pqObjectBuilder.h>
104 #include <pqOptions.h>
105 #include <pqSettings.h>
106 #include <pqServer.h>
107 #include <pqUndoStack.h>
108 #include <pqTabbedMultiViewWidget.h>
109 #include <pqActiveObjects.h>
110 #include <pqHelpReaction.h>
111 #include <pqPluginManager.h>
112 #include <pqPythonDialog.h>
113 #include <pqPythonManager.h>
114 #include <pqLoadDataReaction.h>
115 #include <pqPythonScriptEditor.h>
116 #include <pqDataRepresentation.h>
117 #include <pqDisplayColorWidget.h>
118 #include <pqColorToolbar.h>
119 #include <pqScalarBarVisibilityReaction.h>
120 #include <pqServerResource.h>
121 #include <pqServerConnectReaction.h>
122 #include <pqPluginManager.h>
123 #include <pqVCRToolbar.h>
124 #include <pqAnimationScene.h>
125 #include <pqServerManagerModel.h>
126 #include <pqAnimationTimeToolbar.h>
127
128 //----------------------------------------------------------------------------
129 PVGUI_Module* ParavisModule = 0;
130
131 /*!
132   \mainpage
133   This is the doxygen documentation of the ParaVis module.
134   If you are looking for general information about the structure of the module, you should
135   take a look at the <a href="../index.html">Sphinx documentation</a> first.
136
137   The integration of ParaView into SALOME is split in two parts:
138   \li the PVViewer in the GUI module (folder *src/PVViewer*)
139   \li the ParaVis module itself (the pages you are currently browsing)
140 */
141
142 /*!
143   \class PVGUI_Module
144   \brief Implementation 
145          SALOME module wrapping ParaView GUI.
146 */
147
148 /*!
149   \brief Clean up function
150
151   Used to stop ParaView progress events when
152   exception is caught by global exception handler.
153 */
154 void paravisCleanUp()
155 {
156   if ( pqApplicationCore::instance() ) {
157     pqServer* s = pqApplicationCore::instance()->getActiveServer();
158     if ( s ) s->session()->GetProgressHandler()->CleanupPendingProgress();
159   }
160 }
161
162 /*!
163   \brief Constructor. Sets the default name for the module.
164 */
165 PVGUI_Module::PVGUI_Module()
166   : LightApp_Module( PARAVIS_MODULE_NAME ),
167     mySourcesMenuId( -1 ),
168     myFiltersMenuId( -1 ),
169     myMacrosMenuId(-1),
170     myRecentMenuId(-1),
171     myCatalystMenuId(-1),
172     myOldMsgHandler(0),
173     myTraceWindow(0),
174     myInitTimer(0),
175     myGuiElements(0)
176 {
177 #ifdef HAS_PV_DOC
178   Q_INIT_RESOURCE( PVGUI );
179 #endif
180   ParavisModule = this;
181
182   // Clear old copies of embedded macros files
183   QString aDestPath = QString( "%1/.config/%2/Macros" ).arg( QDir::homePath() ).arg( QApplication::applicationName() );
184   QStringList aFilter;
185   aFilter << "*.py";
186
187   QDir aDestDir(aDestPath);
188   QStringList aDestFiles = aDestDir.entryList(aFilter, QDir::Files);
189   foreach (QString aMacrosPath, getEmbeddedMacrosList()) {
190     QString aMacrosName = QFileInfo(aMacrosPath).fileName();
191     if (aDestFiles.contains(aMacrosName)) {
192       aDestDir.remove(aMacrosName);
193     }
194   }
195 }
196
197 /*!
198   \brief Destructor.
199 */
200 PVGUI_Module::~PVGUI_Module()
201 {
202   if (myInitTimer)
203     delete myInitTimer;
204 }
205
206 /*!
207   \brief Retrieve the PVSERVER CORBA engine.
208   This uses the Python wrapper provided
209   by the PVViewer code in GUI (class PVViewer_EngineWrapper).
210   \sa GetCPPEngine()
211 */
212 PVServer_ServiceWrapper* PVGUI_Module::GetEngine()
213 {
214   return PVServer_ServiceWrapper::GetInstance();
215 }
216
217 /*!
218   \brief Create data model.
219   \return module specific data model
220 */
221 CAM_DataModel* PVGUI_Module::createDataModel()
222 {
223   return new PVGUI_DataModel( this );
224 }
225
226 /*!
227   \brief Get the ParaView application singleton.
228 */
229 pqPVApplicationCore* PVGUI_Module::GetPVApplication()
230 {
231   return PVViewer_Core::GetPVApplication();
232 }
233
234 /*!
235   \brief Initialize module. Creates menus, prepares context menu, etc.
236   \param app SALOME GUI application instance
237 */
238 void PVGUI_Module::initialize( CAM_Application* app )
239 {
240   LightApp_Module::initialize( app );
241
242   // Uncomment to debug ParaView initialization
243   // "aa" used instead of "i" as GDB doesn't like "i" variables :)
244   /*
245   int aa = 1;
246   while( aa ){
247     aa = aa;
248   }
249   */
250
251   LightApp_Application* anApp = getApp();
252   SUIT_Desktop* aDesktop = anApp->desktop();
253
254   // Remember current state of desktop toolbars
255   QList<QToolBar*> foreignToolbars = aDesktop->findChildren<QToolBar*>();
256
257   // Initialize ParaView client and associated behaviors
258   // and connect to externally launched pvserver
259   PVViewer_Core::ParaviewInitApp(aDesktop, anApp->logWindow());
260   myGuiElements = PVViewer_GUIElements::GetInstance(aDesktop);
261
262   // [ABN]: careful with the order of the GUI element creation, the loading of the configuration
263   // and the connection to the server. This order is very sensitive if one wants to make
264   // sure all menus, etc ... are correctly populated.
265   // Reference points are: ParaViewMainWindow.cxx and branded_paraview_initializer.cxx.in
266   setupDockWidgets();
267
268   pvCreateActions();
269   pvCreateMenus();
270   pvCreateToolBars();
271
272   PVViewer_Core::ParaviewInitBehaviors(true, aDesktop);
273
274   QList<QDockWidget*> activeDocks = aDesktop->findChildren<QDockWidget*>();
275   QList<QMenu*> activeMenus = aDesktop->findChildren<QMenu*>();
276
277   // Setup quick-launch shortcuts.
278   QShortcut *ctrlSpace = new QShortcut(Qt::CTRL + Qt::Key_Space, aDesktop);
279   QObject::connect(ctrlSpace, SIGNAL(activated()),
280     pqApplicationCore::instance(), SLOT(quickLaunch()));
281
282   // Find Plugin Dock Widgets
283   QList<QDockWidget*> currentDocks = aDesktop->findChildren<QDockWidget*>();
284   QList<QDockWidget*>::iterator i;
285   for (i = currentDocks.begin(); i != currentDocks.end(); ++i) {
286     if(!activeDocks.contains(*i)) {
287       myDockWidgets[*i] = false; // hidden by default
288       (*i)->hide();
289     }
290   }
291
292     // Find Plugin Menus
293     // [ABN] TODO: fix this - triggers a SEGFAULT at deactivation() time.
294 //    QList<QMenu*> currentMenus = aDesktop->findChildren<QMenu*>();
295 //    QList<QMenu*>::iterator im;
296 //    for (im = currentMenus.begin(); im != currentMenus.end(); ++im) {
297 //      if(!activeMenus.contains(*im)) {
298 //          QString s = (*im)->title();
299 //          std::cout << " MENU "<<  s.toStdString() << std::endl;
300 //          myMenus.append(*im);
301 //      }
302 //    }
303
304   // Connect after toolbar creation, etc ... as some activations of the toolbars is triggered
305   // by the ServerConnection event:
306   const QString configPath(PVViewer_ViewManager::GetPVConfigPath());
307   PVViewer_Core::ParaviewLoadConfigurations(configPath, true);
308   PVViewer_ViewManager::ConnectToExternalPVServer(aDesktop);
309   updateObjBrowser();
310
311   // Find created toolbars
312   QCoreApplication::processEvents();
313
314   // process PVViewer toolbars (might be added by PVViewer created BEFORE activating ParaVis)
315   QList<QToolBar*> pvToolbars = myGuiElements->getToolbars();
316   foreach(QToolBar* aBar, pvToolbars) {
317     if (!myToolbars.contains(aBar)) {
318       myToolbars[aBar] = true;
319       myToolbarBreaks[aBar] = false;
320       aBar->setVisible(false);
321       aBar->toggleViewAction()->setVisible(false);
322     }
323   }
324
325   // process other toolbars (possibly added by Paraview)
326   QList<QToolBar*> allToolbars = aDesktop->findChildren<QToolBar*>();
327   foreach(QToolBar* aBar, allToolbars) {
328     if (!foreignToolbars.contains(aBar) && !myToolbars.contains(aBar)) {
329       myToolbars[aBar] = true;
330       myToolbarBreaks[aBar] = false;
331       aBar->setVisible(false);
332       aBar->toggleViewAction()->setVisible(false);
333     }
334   }
335
336   updateMacros();
337  
338   SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr();
339   bool isStop = aResourceMgr->booleanValue( PARAVIS_MODULE_NAME, "stop_trace", false );
340   if(!isStop)
341     {
342       // Start a timer to schedule asap:
343       //  - the trace start
344       myInitTimer = new QTimer(aDesktop);
345       QObject::connect(myInitTimer, SIGNAL(timeout()), this, SLOT(onInitTimer()) );
346       myInitTimer->setSingleShot(true);
347       myInitTimer->start(0);
348     }
349
350   this->VTKConnect = vtkEventQtSlotConnect::New();
351   
352   vtkProcessModule* pm = vtkProcessModule::GetProcessModule();
353   if(pm) {
354     vtkPVSession* pvs = dynamic_cast<vtkPVSession*>(pm->GetSession());
355     if(pvs) {
356       vtkPVProgressHandler* ph = pvs->GetProgressHandler();
357       if(ph) {
358           this->VTKConnect->Connect(ph, vtkCommand::StartEvent,
359                                     this, SLOT(onStartProgress()));
360           this->VTKConnect->Connect(ph, vtkCommand::EndEvent,
361                                     this, SLOT(onEndProgress()));
362       }
363     }
364   }
365   connect( application(), SIGNAL( appClosed() ), this, SLOT( onStopTrace() ) );
366 }
367
368 /*!
369  * \brief Slot called when the progress bar starts.
370  */
371 void PVGUI_Module::onStartProgress()
372 {
373   // VSR 19/03/2015, issue 0023025
374   // next line is commented: it is bad idea to show wait cursor on ANY vtk event
375   // moreover, it does not work when running pvserver with --multi-client mode
376   //QApplication::setOverrideCursor(Qt::WaitCursor);
377 }
378
379 /*!
380  * \brief Slot called when the progress bar is done.
381  */
382 void PVGUI_Module::onEndProgress()
383 {
384   // VSR 19/03/2015, issue 0023025
385   // next line is commented: it is bad idea to show wait cursor on ANY vtk event
386   // moreover, it does not work when running pvserver with --multi-client mode
387   //QApplication::restoreOverrideCursor();
388 }
389
390 void PVGUI_Module::onDataRepresentationUpdated() {
391   LightApp_Study* activeStudy = dynamic_cast<LightApp_Study*>(application()->activeStudy());
392   if(!activeStudy) return;
393   
394   activeStudy->Modified();
395 }
396
397 /*!
398   \brief Initialisation timer event - Starts up the Python trace
399 */
400 void PVGUI_Module::onInitTimer()
401 {
402   startTrace();
403 }
404   
405 /*!
406   \brief Get list of embedded macros files
407 */
408 QStringList PVGUI_Module::getEmbeddedMacrosList()
409 {
410   QString aRootDir = getenv("PARAVIS_ROOT_DIR");
411
412   QString aSourcePath = aRootDir + "/bin/salome/Macro";
413
414   QStringList aFilter;
415   aFilter << "*.py";
416
417   QDir aSourceDir(aSourcePath);
418   QStringList aSourceFiles = aSourceDir.entryList(aFilter, QDir::Files);
419   QStringList aFullPathSourceFiles;
420   foreach (QString aMacrosName, aSourceFiles) {
421     aFullPathSourceFiles << aSourceDir.absoluteFilePath(aMacrosName);
422   }
423   return aFullPathSourceFiles;
424 }
425
426 /*!
427   \brief Update the list of embedded macros
428 */
429 void PVGUI_Module::updateMacros()
430 {
431   pqPythonManager* aPythonManager = pqPVApplicationCore::instance()->pythonManager();
432   if(!aPythonManager)  {
433     return;
434   }
435   
436   foreach (QString aStr, getEmbeddedMacrosList()) {
437     aPythonManager->addMacro(aStr);
438   }
439 }
440
441
442 /*!
443   \brief Get list of compliant dockable GUI elements
444   \param m map to be filled in ("type":"default_position")
445 */
446 void PVGUI_Module::windows( QMap<int, int>& m ) const
447 {
448   m.insert( LightApp_Application::WT_ObjectBrowser, Qt::LeftDockWidgetArea );
449 #ifndef DISABLE_PYCONSOLE
450   m.insert( LightApp_Application::WT_PyConsole, Qt::BottomDockWidgetArea );
451 #endif
452   // ParaView diagnostic output redirected here
453   m.insert( LightApp_Application::WT_LogWindow, Qt::BottomDockWidgetArea );
454 }
455
456 /*!
457   \brief Shows (toShow = true) or hides ParaView view window
458 */
459 void PVGUI_Module::showView( bool toShow )
460 {
461   // VSR: TODO: all below is not needed, if we use standard approach
462   // that consists in implementing viewManagers() function properly
463   // This should be done after we decide what to do with Log window.
464   LightApp_Application* anApp = getApp();
465   PVViewer_ViewManager* viewMgr =
466     dynamic_cast<PVViewer_ViewManager*>( anApp->getViewManager( PVViewer_Viewer::Type(), false ) );
467   if ( !viewMgr ) {
468     viewMgr = new PVViewer_ViewManager( anApp->activeStudy(), anApp->desktop(), anApp->logWindow() );
469     anApp->addViewManager( viewMgr );
470     connect( viewMgr, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
471              anApp, SLOT( onCloseView( SUIT_ViewManager* ) ) );
472   }
473
474   PVViewer_ViewWindow* pvWnd = dynamic_cast<PVViewer_ViewWindow*>( viewMgr->getActiveView() );
475   if ( !pvWnd ) {
476     pvWnd = dynamic_cast<PVViewer_ViewWindow*>( viewMgr->createViewWindow() );
477     // this also connects to the pvserver and instantiates relevant PV behaviors
478   }
479
480   pvWnd->setVisible( toShow );
481   if ( toShow ) pvWnd->setFocus();
482 }
483
484 /*!
485   \brief Slot to show help for proxy.
486 */
487 void PVGUI_Module::showHelpForProxy( const QString& groupname, const QString& proxyname )
488 {
489   pqHelpReaction::showProxyHelp(groupname, proxyname);
490 }
491
492 /*!
493   \brief Slot to show the waiting state.
494 */
495 void PVGUI_Module::onPreAccept()
496 {
497   getApp()->desktop()->statusBar()->showMessage(tr("STB_PREACCEPT"));
498   QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
499 }
500
501 /*!
502   \brief Slot to show the ready state.
503 */
504 void PVGUI_Module::onPostAccept()
505 {
506   getApp()->desktop()->statusBar()->showMessage(tr("STB_POSTACCEPT"), 2000);
507   QTimer::singleShot(0, this, SLOT(endWaitCursor()));
508 }
509
510 /*!
511   \brief Slot to switch off wait cursor.
512 */
513 void PVGUI_Module::endWaitCursor()
514 {
515   QApplication::restoreOverrideCursor();
516 }
517 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
518 /*!
519   \brief Handler method for the output of messages.
520 */
521 static void ParavisMessageOutput(QtMsgType type, const char *msg)
522 {
523   switch(type)
524     {
525   case QtDebugMsg:
526     vtkOutputWindow::GetInstance()->DisplayText(msg);
527     break;
528   case QtWarningMsg:
529     vtkOutputWindow::GetInstance()->DisplayErrorText(msg);
530     break;
531   case QtCriticalMsg:
532     vtkOutputWindow::GetInstance()->DisplayErrorText(msg);
533     break;
534   case QtFatalMsg:
535     vtkOutputWindow::GetInstance()->DisplayErrorText(msg);
536     break;
537     }
538 }
539 #else
540 /*!
541   \brief Handler method for the output of messages.
542 */
543 static void ParavisMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
544 {
545   switch(type)
546     {
547   case QtDebugMsg:
548     vtkOutputWindow::GetInstance()->DisplayText(msg.toLatin1().constData());
549     break;
550   case QtWarningMsg:
551     vtkOutputWindow::GetInstance()->DisplayErrorText(msg.toLatin1().constData());
552     break;
553   case QtCriticalMsg:
554     vtkOutputWindow::GetInstance()->DisplayErrorText(msg.toLatin1().constData());
555     break;
556   case QtFatalMsg:
557     vtkOutputWindow::GetInstance()->DisplayErrorText(msg.toLatin1().constData());
558     break;
559     }
560 }
561 #endif
562 /*!
563   \brief Activate module.
564   \param study current study
565   \return \c true if activaion is done successfully or 0 to prevent
566   activation on error
567 */
568 bool PVGUI_Module::activateModule( SUIT_Study* study )
569 {
570 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
571   myOldMsgHandler = qInstallMsgHandler(ParavisMessageOutput);
572 #else
573   myOldMsgHandler = qInstallMessageHandler(ParavisMessageOutput);
574 #endif  
575   SUIT_ExceptionHandler::addCleanUpRoutine( paravisCleanUp );
576
577   storeCommonWindowsState();
578
579   bool isDone = LightApp_Module::activateModule( study );
580   if ( !isDone ) return false;
581
582   showView( true );
583   if ( mySourcesMenuId != -1 ) menuMgr()->show(mySourcesMenuId);
584   if ( myFiltersMenuId != -1 ) menuMgr()->show(myFiltersMenuId);
585   if ( myMacrosMenuId != -1 ) menuMgr()->show(myMacrosMenuId);
586   if ( myCatalystMenuId != -1 ) menuMgr()->show(myCatalystMenuId);
587
588   // Update the various menus with the content pre-loaded in myGuiElements
589 //  QMenu* srcMenu = menuMgr()->findMenu( mySourcesMenuId );
590 //  myGuiElements->updateSourcesMenu(srcMenu);
591 //  QMenu* filtMenu = menuMgr()->findMenu( myFiltersMenuId );
592 //  myGuiElements->updateFiltersMenu(filtMenu);
593 //  QMenu* macMenu = menuMgr()->findMenu( myMacrosMenuId );
594 //  myGuiElements->updateMacrosMenu(macMenu);
595
596   setMenuShown( true );
597   setToolShown( true );
598
599   restoreDockWidgetsState();
600
601   QMenu* aMenu = menuMgr()->findMenu( myRecentMenuId );
602   if(aMenu) {
603     QList<QAction*> anActns = aMenu->actions();
604     for (int i = 0; i < anActns.size(); ++i) {
605       QAction* a = anActns.at(i);
606       if(a)
607         a->setVisible(true);
608     }
609   }
610
611   QList<QMenu*>::iterator it;
612   for (it = myMenus.begin(); it != myMenus.end(); ++it) {
613     QAction* a = (*it)->menuAction();
614     if(a)
615       a->setVisible(true);
616   }
617
618   if ( myRecentMenuId != -1 ) menuMgr()->show(myRecentMenuId);
619   
620   return isDone;
621 }
622
623
624 /*!
625   \brief Deactivate module.
626   \param study current study
627   \return \c true if deactivaion is done successfully or 0 to prevent
628   deactivation on error
629 */
630 bool PVGUI_Module::deactivateModule( SUIT_Study* study )
631 {
632   MESSAGE("PARAVIS deactivation ...")
633
634   QMenu* aMenu = menuMgr()->findMenu( myRecentMenuId );
635   if(aMenu) {
636     QList<QAction*> anActns = aMenu->actions();
637     for (int i = 0; i < anActns.size(); ++i) {
638       QAction* a = anActns.at(i);
639       if(a)
640         a->setVisible(false);
641     }
642   }
643
644   QList<QMenu*>::iterator it;
645   for (it = myMenus.begin(); it != myMenus.end(); ++it) {
646     QAction* a = (*it)->menuAction();
647     if(a)
648       a->setVisible(false);
649   }
650
651   QList<QDockWidget*> aStreamingViews = application()->desktop()->findChildren<QDockWidget*>("pqStreamingControls");
652   foreach(QDockWidget* aView, aStreamingViews) {
653     if (!myDockWidgets.contains(aView))
654       myDockWidgets[aView] = aView->isVisible();
655   }
656
657   /*if (pqImplementation::helpWindow) {
658     pqImplementation::helpWindow->hide();
659     }*/
660   // hide menus
661   menuMgr()->hide(myRecentMenuId);
662   menuMgr()->hide(mySourcesMenuId);
663   menuMgr()->hide(myFiltersMenuId);
664   menuMgr()->hide(myMacrosMenuId);
665   menuMgr()->hide(myCatalystMenuId);
666   setMenuShown( false );
667   setToolShown( false );
668
669   saveDockWidgetsState();
670
671   SUIT_ExceptionHandler::removeCleanUpRoutine( paravisCleanUp );
672
673   if (myOldMsgHandler)
674 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
675     qInstallMsgHandler(myOldMsgHandler);
676 #else
677     qInstallMessageHandler(myOldMsgHandler);
678 #endif
679   restoreCommonWindowsState();
680   
681   return LightApp_Module::deactivateModule( study );
682 }
683
684
685 /*!
686   \brief Called when application is closed.
687
688   Process finalize application functionality from ParaView in order to save server settings
689   and nullify application pointer if the application is being closed.
690
691   \param theApp application
692 */
693 void PVGUI_Module::onApplicationClosed( SUIT_Application* theApp )
694 {
695   PVViewer_Core::ParaviewCleanup();
696   CAM_Module::onApplicationClosed(theApp);
697 }
698
699 /*!
700   \brief Called when study is closed.
701
702   Removes data model from the \a study.
703
704   \param study study being closed
705 */
706 void PVGUI_Module::studyClosed(SUIT_Study* study)
707 {
708   showView(false); // VSR: this seems to be not needed (all views are automatically closed)
709   clearParaviewState();
710   //Re-start trace 
711   onRestartTrace();
712
713   LightApp_Module::studyClosed(study);
714 }
715
716 /*!
717   \brief Open file of format supported by ParaView
718 */
719 void PVGUI_Module::openFile( const char* theName )
720 {
721   QStringList aFiles;
722   aFiles << theName;
723   pqLoadDataReaction::loadData( aFiles );
724 }
725
726 /*!
727   \brief Starts Python trace.
728  
729   Start trace invoking the newly introduced C++ API (PV 4.2)
730   (inspired from pqTraceReaction::start())
731 */
732 void PVGUI_Module::startTrace()
733 {
734   vtkSMSessionProxyManager* pxm = pqActiveObjects::instance().activeServer()->proxyManager();
735
736   vtkSmartPointer<vtkSMProxy> proxy;
737   proxy.TakeReference( pxm->NewProxy( "pythontracing", "PythonTraceOptions" ) );
738   if ( proxy ) {
739     vtkNew<vtkSMParaViewPipelineController> controller;
740     controller->InitializeProxy( proxy );
741   }
742   vtkSMTrace* trace = vtkSMTrace::StartTrace();
743   if ( proxy ) {
744     // Set manually the properties entered via the dialog box poping-up when requiring
745     // a trace start in PV4.2 (trace options)
746     SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr();
747     int type = aResourceMgr->integerValue( PARAVIS_MODULE_NAME, "tracestate_type", 2 );
748     trace->SetPropertiesToTraceOnCreate( type );
749     trace->SetFullyTraceSupplementalProxies( false );
750   }
751 }
752
753 /*!
754   \brief Stops Python trace.
755 */
756 void PVGUI_Module::stopTrace()
757 {
758   vtkSMTrace::StopTrace();
759 }
760
761 /*!
762   \brief Execute a Python script.
763 */
764 void PVGUI_Module::executeScript( const char* script )
765 {
766 #ifndef WNT
767   pqPythonManager* manager = qobject_cast<pqPythonManager*>(
768                              pqApplicationCore::instance()->manager( "PYTHON_MANAGER" ) );
769   if ( manager )  {
770     pqPythonDialog* pyDiag = manager->pythonShellDialog();
771     if ( pyDiag ) {
772       pyDiag->runString(script);  
773     }
774   }
775 #endif
776 }
777
778 ///**
779 // *  Debug function printing out the given interpreter's execution context
780 // */
781 //void printInterpContext(PyInterp_Interp * interp )
782 //{
783 //  // Extract __smtraceString from interpreter's context
784 //  const PyObject* ctxt = interp->getExecutionContext();
785 //
786 //  PyObject* lst = PyDict_Keys((PyObject *)ctxt);
787 //  Py_ssize_t siz = PyList_GET_SIZE(lst);
788 //  for (Py_ssize_t i = 0; i < siz; i++)
789 //    {
790 //      PyObject * elem = PyList_GetItem(lst, i);
791 //      if (PyString_Check(elem))
792 //        {
793 //          std::cout << "At pos:" << i << ", " << PyString_AsString(elem) << std::endl;
794 //        }
795 //      else
796 //        std::cout << "At pos:" << i << ", not a string!" << std::endl;
797 //    }
798 //  Py_XDECREF(lst);
799 //}
800
801 /*!
802   \brief Returns trace string
803 */
804 QString PVGUI_Module::getTraceString()
805 {
806   QString traceString = "";
807
808   static const QString replaceStr( "paraview.simple" );
809   std::stringstream nl;
810   nl << std::endl; // surely there is some Qt trick to do that in a portable way??
811   QString end_line( nl.str().c_str() );
812
813   vtkSMTrace* tracer = vtkSMTrace::GetActiveTracer();
814   if ( tracer ) {
815     traceString = tracer->GetCurrentTrace();
816     // 'import pvsimple' is necessary to fix the first call to DisableFirstRenderCamera in the paraview trace
817     // 'ShowParaviewView()' ensure there is an opened viewing window (otherwise SEGFAULT!)
818     traceString = "import pvsimple" + end_line +
819       "pvsimple.ShowParaviewView()" + end_line + traceString;
820
821     // Replace import "paraview.simple" by "pvsimple"
822     if ( !traceString.isEmpty() ) {
823       int aPos = traceString.indexOf( replaceStr );
824       while ( aPos != -1 ) {
825         traceString = traceString.replace( aPos, replaceStr.length(), "pvsimple" );
826         aPos = traceString.indexOf( replaceStr, aPos );
827       }
828     }
829   }
830
831   // Save camera position to, which is no longer output by the tracer ...
832   {
833     vtkPythonScopeGilEnsurer psge;
834     PyObject * mods(PySys_GetObject(const_cast<char*>("modules")));
835     PyObject * trace_mod(PyDict_GetItemString(mods, "paraview.smtrace"));  // module was already (really) imported by vtkSMTrace
836     if (PyModule_Check(trace_mod)) {
837         vtkSmartPyObject save_cam(PyObject_GetAttrString(trace_mod, const_cast<char*>("SaveCameras")));
838         vtkSmartPyObject camera_trace(PyObject_CallMethod(save_cam, const_cast<char*>("get_trace"), NULL));
839         // Convert to a single string
840         vtkSmartPyObject ret(PyString_FromString(end_line.toStdString().c_str()));
841         vtkSmartPyObject final_string(PyObject_CallMethod(ret, const_cast<char*>("join"),
842             const_cast<char*>("O"), (PyObject*)camera_trace));
843         if (PyString_CheckExact(final_string))
844           {
845             QString camera_qs(PyString_AsString(final_string));  // deep copy
846             traceString = traceString + end_line  + end_line + QString("#### saving camera placements for all active views")
847                 + end_line + end_line + camera_qs + end_line;
848           }
849       }
850   } 
851
852   return traceString;
853 }
854
855 /*!
856   \brief Saves trace string to disk file
857 */
858 void PVGUI_Module::saveTrace( const char* theName )
859 {
860   QFile file( theName );
861   if ( !file.open( QIODevice::WriteOnly | QIODevice::Text ) ) {
862     MESSAGE( "Could not open file:" << theName );
863     return;
864   }
865   QTextStream out( &file );
866   out << getTraceString();
867   file.close();
868 }
869
870 /*!
871   \brief Saves ParaView state to a disk file
872 */
873 void PVGUI_Module::saveParaviewState( const QString& theFileName )
874 {
875   pqApplicationCore::instance()->saveState( theFileName.toStdString().c_str() );
876 }
877
878 /*!
879   \brief Delete all objects for Paraview Pipeline Browser
880 */
881 void PVGUI_Module::clearParaviewState()
882 {
883   QAction* deleteAllAction = action( DeleteAllId );
884   if ( deleteAllAction ) {
885     deleteAllAction->activate( QAction::Trigger );
886   }
887 }
888
889 /*!
890   \brief Restores ParaView state from a disk file
891 */
892 void PVGUI_Module::loadParaviewState( const QString& theFileName )
893 {
894   pqApplicationCore::instance()->loadState( theFileName.toStdString().c_str(), getActiveServer() );
895 }
896
897 /*!
898   \brief Returns current active ParaView server
899 */
900 pqServer* PVGUI_Module::getActiveServer()
901 {
902   return pqApplicationCore::instance()->getActiveServer();
903 }
904
905
906 /*!
907   \brief Creates PARAVIS preferences panel.
908 */
909 void PVGUI_Module::createPreferences()
910 {
911   QList<QVariant> aIndices;
912   QStringList aStrings;
913
914   // Paraview settings tab
915   int aParaViewSettingsTab = addPreference( tr( "TIT_PVIEWSETTINGS" ) );
916
917   setPreferenceProperty(aParaViewSettingsTab, "stretch", false );
918   int aPanel = addPreference( QString(), aParaViewSettingsTab,
919                               LightApp_Preferences::UserDefined, PARAVIS_MODULE_NAME, "" );
920
921   setPreferenceProperty( aPanel, "content", (qint64)( new PVGUI_ParaViewSettingsPane( 0, getApp() ) ) );
922
923   // Paravis settings tab
924   int aParaVisSettingsTab = addPreference( tr( "TIT_PVISSETTINGS" ) );
925
926   addPreference( tr( "PREF_NO_EXT_PVSERVER" ), aParaVisSettingsTab, 
927                  LightApp_Preferences::Bool, PARAVIS_MODULE_NAME, "no_ext_pv_server" );
928
929   int aSaveType = addPreference( tr( "PREF_SAVE_TYPE_LBL" ), aParaVisSettingsTab,
930                                  LightApp_Preferences::Selector,
931                                  PARAVIS_MODULE_NAME, "savestate_type" );
932
933   aStrings.clear();
934   aIndices.clear();
935   aIndices << 0 << 1 << 2;
936   aStrings << tr("PREF_SAVE_TYPE_0") << tr("PREF_SAVE_TYPE_1") << tr("PREF_SAVE_TYPE_2");
937   setPreferenceProperty( aSaveType, "strings", aStrings );
938   setPreferenceProperty( aSaveType, "indexes", aIndices );
939
940   // ... "Language" group <<start>>
941   int traceGroup = addPreference( tr( "PREF_GROUP_TRACE" ), aParaVisSettingsTab );
942
943   int stopTrace = addPreference( tr( "PREF_STOP_TRACE" ), traceGroup, 
944                                  LightApp_Preferences::Bool, PARAVIS_MODULE_NAME, "stop_trace" );
945   setPreferenceProperty( stopTrace, "restart",  true );
946
947   int aTraceType = addPreference( tr( "PREF_TRACE_TYPE_LBL" ), traceGroup,
948                                  LightApp_Preferences::Selector,
949                                  PARAVIS_MODULE_NAME, "tracestate_type" );
950   aStrings.clear();
951   aIndices.clear();
952   aIndices << 0 << 1 << 2;
953   aStrings << tr("PREF_TRACE_TYPE_0") << tr("PREF_TRACE_TYPE_1") << tr("PREF_TRACE_TYPE_2");
954   setPreferenceProperty( aTraceType, "strings", aStrings );
955   setPreferenceProperty( aTraceType, "indexes", aIndices );
956   setPreferenceProperty( aTraceType, "restart",  true );
957 }
958
959 /*!
960   \brief. Show ParaView python trace.
961 */
962 void PVGUI_Module::onShowTrace()
963 {
964   if (!myTraceWindow) {
965     myTraceWindow = new pqPythonScriptEditor(getApp()->desktop());
966   }
967   myTraceWindow->setText(getTraceString());
968   myTraceWindow->show();
969   myTraceWindow->raise();
970   myTraceWindow->activateWindow();
971 }
972
973
974 /*!
975   \brief. Re-initialize ParaView python trace.
976 */
977 void PVGUI_Module::onRestartTrace()
978 {
979   stopTrace();
980   startTrace();
981 }
982
983 /*!
984   \brief. Close ParaView python trace.
985 */
986 void PVGUI_Module::onStopTrace()
987 {
988   stopTrace();
989 }
990 /*!
991   \brief Called when view manager is added
992 */
993 void PVGUI_Module::onViewManagerAdded( SUIT_ViewManager* vm )
994 {
995   if ( PVViewer_ViewManager* pvvm = dynamic_cast<PVViewer_ViewManager*>( vm ) ) {
996     connect( pvvm, SIGNAL( viewCreated( SUIT_ViewWindow* ) ), 
997              this, SLOT( onPVViewCreated( SUIT_ViewWindow* ) ) );
998     connect( pvvm, SIGNAL( deleteView( SUIT_ViewWindow* ) ),
999              this,  SLOT( onPVViewDelete( SUIT_ViewWindow* ) ) );
1000   }
1001 }
1002
1003 /*!
1004   \brief Called when view manager is removed
1005 */
1006 void PVGUI_Module::onViewManagerRemoved( SUIT_ViewManager* vm )
1007 {
1008   if ( PVViewer_ViewManager* pvvm = dynamic_cast<PVViewer_ViewManager*>( vm ) )
1009     disconnect( pvvm, SIGNAL( viewCreated( SUIT_ViewWindow* ) ),
1010                 this, SLOT( onPVViewCreated( SUIT_ViewWindow* ) ) );
1011 }
1012
1013 /*!
1014   \brief Show toolbars at \a vw PV view window creating when PARAVIS is active.
1015 */
1016 void PVGUI_Module::onPVViewCreated( SUIT_ViewWindow* vw )
1017 {
1018   myGuiElements->setToolBarVisible( true );
1019   restoreDockWidgetsState();
1020 }
1021
1022 /*!
1023   \brief Save toolbars state at \a view view closing.
1024 */
1025 void PVGUI_Module::onPVViewDelete( SUIT_ViewWindow* view )
1026 {
1027   if ( dynamic_cast<PVViewer_ViewWindow*>( view ) )
1028     saveDockWidgetsState( false );
1029 }
1030
1031 /*!
1032   \fn CAM_Module* createModule();
1033   \brief Export module instance (factory function).
1034   \return new created instance of the module
1035 */
1036
1037 #ifdef WNT
1038 #define PVGUI_EXPORT __declspec(dllexport)
1039 #else   // WNT
1040 #define PVGUI_EXPORT
1041 #endif  // WNT
1042
1043 extern "C" {
1044
1045   bool flag = false;
1046   PVGUI_EXPORT CAM_Module* createModule() {
1047     return new PVGUI_Module();
1048   }
1049   
1050   PVGUI_EXPORT char* getModuleVersion() {
1051     return (char*)PARAVIS_VERSION_STR;
1052   }
1053 }