Salome HOME
Fixed: contextual menu in pipeline browser + VCR controls
[modules/paravis.git] / src / PVGUI / PVGUI_Module.cxx
1 // PARAVIS : ParaView wrapper SALOME module
2 //
3 // Copyright (C) 2010-2014  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 #include "PVGUI_Module.h"
31
32 //#ifdef PARAVIS_WITH_FULL_CORBA
33 //# include "PARAVIS_Gen_i.hh"
34 //#endif
35
36 #include CORBA_SERVER_HEADER(SALOME_ModuleCatalog)
37 #include CORBA_SERVER_HEADER(SALOMEDS)
38
39 #include "PVViewer_ViewManager.h"
40 #include "PVViewer_ViewWindow.h"
41 #include "PVViewer_ViewModel.h"
42 #include "PVGUI_Tools.h"
43 #include "PVGUI_ParaViewSettingsPane.h"
44 #include "PVViewer_GUIElements.h"
45 #include "PVViewer_EngineWrapper.h"
46 #include "PVGUI_DataModel.h"
47
48 // SALOME Includes
49 #include <utilities.h>
50 #include <SUIT_DataBrowser.h>
51 #include <SUIT_Desktop.h>
52 #include <SUIT_MessageBox.h>
53 #include <SUIT_ResourceMgr.h>
54 #include <SUIT_Session.h>
55 #include <SUIT_OverrideCursor.h>
56 #include <SUIT_ExceptionHandler.h>
57
58 #include <SALOME_LifeCycleCORBA.hxx>
59 #include <SALOMEDS_SObject.hxx>
60
61 #include <LightApp_SelectionMgr.h>
62 #include <LightApp_NameDlg.h>
63 #include <LightApp_Application.h>
64 #include <SalomeApp_Application.h>  // should ultimately be a LightApp only
65 #include <SalomeApp_Study.h>
66 #include <SALOME_ListIO.hxx>
67 #include <SALOMEDS_Tool.hxx>
68 #include <Utils_ORB_INIT.hxx>
69 #include <Utils_SINGLETON.hxx>
70
71 #include <QtxActionMenuMgr.h>
72 #include <QtxActionToolMgr.h>
73
74 #include <PARAVIS_version.h>
75
76 // External includes
77 #include <sstream>
78
79 #include <QAction>
80 #include <QApplication>
81 #include <QCursor>
82 #include <QDir>
83 #include <QFile>
84 #include <QFileInfo>
85 #include <QIcon>
86 #include <QInputDialog>
87 #include <QMenu>
88 #include <QStatusBar>
89 #include <QString>
90 #include <QStringList>
91 #include <QTimer>
92 #include <QToolBar>
93 #include <QTextStream>
94 #include <QShortcut>
95 #include <QDockWidget>
96 #include <QHelpEngine>
97
98 // Paraview includes
99 #include <vtkPVConfig.h>  // for symbol PARAVIEW_VERSION
100 #include <vtkProcessModule.h>
101 #include <vtkPVSession.h>
102 #include <vtkPVProgressHandler.h>
103 #include <vtkOutputWindow.h>
104 #include <vtkEventQtSlotConnect.h>
105 #include <vtkNew.h>
106 #include <vtkSMProxy.h>
107 #include <vtkSmartPointer.h>
108 #include <vtkSMSession.h>
109 #include <vtkSMTrace.h>
110 #include <vtkSMSessionProxyManager.h>
111 #include <vtkSMParaViewPipelineController.h>
112
113 #include <pqApplicationCore.h>
114 #include <pqPVApplicationCore.h>
115 #include <pqActiveView.h>
116 #include <pqObjectBuilder.h>
117 #include <pqOptions.h>
118 #include <pqSettings.h>
119 #include <pqServer.h>
120 #include <pqUndoStack.h>
121 #include <pqTabbedMultiViewWidget.h>
122 #include <pqActiveObjects.h>
123 #include <pqHelpReaction.h>
124 #include <pqPluginManager.h>
125 #include <pqPythonDialog.h>
126 #include <pqPythonManager.h>
127 #include <pqLoadDataReaction.h>
128 #include <pqPythonScriptEditor.h>
129 #include <pqDataRepresentation.h>
130 #include <pqDisplayColorWidget.h>
131 #include <pqColorToolbar.h>
132 #include <pqScalarBarVisibilityReaction.h>
133 #include <pqServerResource.h>
134 #include <pqServerConnectReaction.h>
135
136 // TO REMOVE:
137 #include <PyInterp_Interp.h>
138
139 #include <PVViewer_EngineWrapper.h>
140
141
142 //----------------------------------------------------------------------------
143 PVGUI_Module* ParavisModule = 0;
144 PVSERVER_ORB::PVSERVER_Gen_var PVGUI_Module::MyEngine;
145
146 /*!
147   \mainpage
148   TODO TODO update this:
149
150   <h2>Building and installing PARAVIS</h2>
151   As any other SALOME module, PARAVIS requires PARAVIS_ROOT_DIR environment variable to be set to PARAVIS
152   installation directory.
153   Other variables needed for correct detection of ParaView location:
154   \li PVHOME - points at the ParaView installation directory tree
155   \li PVVERSION - number of ParaView version
156
157   It also requires common SALOME environment including GUI_ROOT_DIR and other prerequsites.
158
159
160   PARAVIS module can be launched using the following commands:
161   \li Full SALOME configuration
162   \code
163   runSalome --modules="PARAVIS"
164   \endcode
165
166   <h2>ParaView GUI integration</h2>
167   <h3>ParaView GUI integration overview</h3>
168
169   The main idea is to reuse ParaView GUI internal logic as much as possible, providing a layer 
170   between it and SALOME GUI that hides the following SALOME GUI implementation details from ParaView:
171
172   \li SALOME GUI executable and Qt event loop
173   \li SALOME GUI desktop
174   \li Dock windows areas
175   \li SALOME menu and toolbar managers
176
177   Major part of the integration is implemented in PVGUI_Module class.
178
179   <h3>ParaView client initalization</h3>
180
181   ParaView client initalization is performed when an instance of PVGUI_Module class has been created 
182   and \link PVGUI_Module::initialize() PVGUI_Module::initialize()\endlink method is called by SALOME GUI.
183   The actual client start-up is done in \link PVGUI_Module::pvInit() PVGUI_Module::pvInit()\endlink method. 
184   
185
186   <h3>Multi-view manager</h3>
187
188   SALOME GUI requires that each kind of view be implemnted with help of (at least) three classes. For ParaView multi-view manager 
189   these are:
190
191   \li PVGUI_ViewManager - view manager class
192   \li PVGUI_Viewer      - view model class
193   \li PVGUI_ViewWindow  - view window class that acts as a parent for %pqViewManager
194
195   Single instances of PVGUI_ViewManager and PVGUI_ViewWindow classes are created by \link PVGUI_Module::showView() 
196   PVGUI_Module::showView()\endlink method upon the first PARAVIS module activation. The same method hides the multi-view manager 
197   when the module is deactivated (the user switches to another module or a study is closed). 
198   A special trick is used to make PVGUI_ViewWindow the parent of %pqViewManager widget. It is created initally by %pqMainWindowCore
199   with the desktop as a parent, so when it is shown PVGUI_ViewWindow instance is passed to its setParent() method. In  
200   \link PVGUI_ViewWindow::~PVGUI_ViewWindow() PVGUI_ViewWindow::~PVGUI_ViewWindow()\endlink the parent is nullified to avoid deletion
201   of %pqViewManager widget that would break %pqMainWindowCore class.
202
203   <h3>ParaView plugins</h3>
204   ParaView server and client plugins are managed by %pqMainWindowCore slots that has full access to PARAVIS menus and toolbars. 
205   As a result they appears automatically in PARAVIS menus and toolbars if loaded successfully.
206 */
207
208 /*!
209   \class PVGUI_Module
210   \brief Implementation 
211          SALOME module wrapping ParaView GUI.
212 */
213
214 _PTR(SComponent)
215 ClientFindOrCreateParavisComponent(_PTR(Study) theStudyDocument)
216 {
217   _PTR(SComponent) aSComponent = theStudyDocument->FindComponent("PVSERVER");
218   if (!aSComponent) {
219     _PTR(StudyBuilder) aStudyBuilder = theStudyDocument->NewBuilder();
220     aStudyBuilder->NewCommand();
221     int aLocked = theStudyDocument->GetProperties()->IsLocked();
222     if (aLocked) theStudyDocument->GetProperties()->SetLocked(false);
223     aSComponent = aStudyBuilder->NewComponent("PVSERVER");
224     _PTR(GenericAttribute) anAttr =
225       aStudyBuilder->FindOrCreateAttribute(aSComponent, "AttributeName");
226     _PTR(AttributeName) aName (anAttr);
227
228     ORB_INIT& init = *SINGLETON_<ORB_INIT>::Instance();
229     CORBA::ORB_var anORB = init( qApp->argc(), qApp->argv() );
230
231     SALOME_NamingService *NamingService = new SALOME_NamingService( anORB );
232     CORBA::Object_var objVarN = NamingService->Resolve("/Kernel/ModulCatalog");
233     SALOME_ModuleCatalog::ModuleCatalog_var Catalogue =
234       SALOME_ModuleCatalog::ModuleCatalog::_narrow(objVarN);
235     SALOME_ModuleCatalog::Acomponent_var Comp = Catalogue->GetComponent( "PVSERVER" );
236     if (!Comp->_is_nil()) {
237       aName->SetValue(Comp->componentusername());
238     }
239
240     anAttr = aStudyBuilder->FindOrCreateAttribute(aSComponent, "AttributePixMap");
241     _PTR(AttributePixMap) aPixmap (anAttr);
242     aPixmap->SetPixMap( "pqAppIcon16.png" );
243
244     // Create Attribute parameters for future using
245     anAttr = aStudyBuilder->FindOrCreateAttribute(aSComponent, "AttributeParameter");
246
247     aStudyBuilder->DefineComponentInstance(aSComponent, PVGUI_Module::GetCPPEngine()->GetIOR());
248     if (aLocked) theStudyDocument->GetProperties()->SetLocked(true);
249     aStudyBuilder->CommitCommand();
250   }
251   return aSComponent;
252 }
253
254 /*!
255   Clean up function; used to stop ParaView progress events when
256   exception is caught by global exception handler.
257 */
258 void paravisCleanUp()
259 {
260   if ( pqApplicationCore::instance() ) {
261     pqServer* s = pqApplicationCore::instance()->getActiveServer();
262     if ( s ) s->session()->GetProgressHandler()->CleanupPendingProgress();
263   }
264 }
265
266 /*!
267   \brief Constructor. Sets the default name for the module.
268 */
269 PVGUI_Module::PVGUI_Module()
270     : SalomeApp_Module( PARAVIS_MODULE_NAME ),
271     mySelectionControlsTb( -1 ),
272     mySourcesMenuId( -1 ),
273     myFiltersMenuId( -1 ),
274     myMacrosMenuId(-1),
275     myToolbarsMenuId(-1),
276     myRecentMenuId(-1),
277     myOldMsgHandler(0),
278     myTraceWindow(0),
279     myStateCounter(0),
280     myInitTimer(0),
281     myPushTraceTimer(0),
282     myGuiElements(0)
283 {
284 #ifdef HAS_PV_DOC
285   Q_INIT_RESOURCE( PVGUI );
286 #endif
287   ParavisModule = this;
288
289   // Clear old copies of embedded macros files
290   QString aDestPath = QString( "%1/.config/%2/Macros" ).arg( QDir::homePath() ).arg( QApplication::applicationName() );
291   QStringList aFilter;
292   aFilter << "*.py";
293
294   QDir aDestDir(aDestPath);
295   QStringList aDestFiles = aDestDir.entryList(aFilter, QDir::Files);
296   foreach (QString aMacrosPath, getEmbeddedMacrosList()) {
297     QString aMacrosName = QFileInfo(aMacrosPath).fileName();
298     if (aDestFiles.contains(aMacrosName)) {
299       aDestDir.remove(aMacrosName);
300     }
301   }
302 }
303
304 /*!
305   \brief Destructor.
306 */
307 PVGUI_Module::~PVGUI_Module()
308 {
309   if (myPushTraceTimer)
310     delete myPushTraceTimer;
311   if (myInitTimer)
312     delete myInitTimer;
313 }
314
315 PVViewer_EngineWrapper * PVGUI_Module::GetEngine()
316 {
317   return PVViewer_EngineWrapper::GetInstance();
318 }
319
320 PVSERVER_ORB::PVSERVER_Gen_var PVGUI_Module::GetCPPEngine()
321 {
322   // initialize PARAVIS module engine (load, if necessary)
323   if ( CORBA::is_nil( MyEngine ) ) {
324       Engines::EngineComponent_var comp =
325           SalomeApp_Application::lcc()->FindOrLoad_Component( "FactoryServer", "PVSERVER" );
326       MyEngine = PVSERVER_ORB::PVSERVER_Gen::_narrow( comp );
327  }
328   return MyEngine;
329 }
330
331 /*!
332   \brief Create data model.
333   \return module specific data model
334 */
335 CAM_DataModel* PVGUI_Module::createDataModel()
336 {
337   return new PVGUI_DataModel( this );
338 }
339
340 pqPVApplicationCore * PVGUI_Module::GetPVApplication()
341 {
342   return PVViewer_ViewManager::GetPVApplication();
343 }
344
345 /*!
346   \brief Initialize module. Creates menus, prepares context menu, etc.
347   \param app SALOME GUI application instance
348 */
349 void PVGUI_Module::initialize( CAM_Application* app )
350 {
351   LightApp_Module::initialize( app );
352
353   // Create ParaViS actions
354   createActions();
355   // Create ParaViS menus
356   createMenus();
357
358   // Uncomment to debug ParaView initialization
359   // "aa" used instead of "i" as GDB doesn't like "i" variables :)
360   /*
361   int aa = 1;
362   while( aa ){
363     aa = aa;
364   }
365   */
366
367   LightApp_Application* anApp = getApp();
368   SUIT_Desktop* aDesktop = anApp->desktop();
369
370   // Initialize ParaView client and associated behaviors
371   // and connect to externally launched pvserver
372   PVViewer_ViewManager::ParaviewInitApp(aDesktop, anApp->logWindow());
373   myGuiElements = PVViewer_GUIElements::GetInstance(aDesktop);
374
375   // Remember current state of desktop toolbars
376   QList<QToolBar*> foreignToolbars = aDesktop->findChildren<QToolBar*>();
377
378   setupDockWidgets();
379
380   // Behaviors and connection must be instanciated *after* widgets are in place
381   // In PARAVIS module we do not wait for PVViewer_ViewWindow to be instanciated to have this:
382   PVViewer_ViewManager::ParaviewInitBehaviors(true, aDesktop);
383
384   pvCreateActions();
385   pvCreateMenus();
386   pvCreateToolBars();
387
388   // Connect after toolbar creation, etc ... as some activations of the toolbars is triggered
389   // by the ServerConnection event:
390   PVViewer_ViewManager::ConnectToExternalPVServer(aDesktop);
391
392   QList<QDockWidget*> activeDocks = aDesktop->findChildren<QDockWidget*>();
393   QList<QMenu*> activeMenus = aDesktop->findChildren<QMenu*>();
394
395   // Setup quick-launch shortcuts.
396   QShortcut *ctrlSpace = new QShortcut(Qt::CTRL + Qt::Key_Space, aDesktop);
397   QObject::connect(ctrlSpace, SIGNAL(activated()),
398     pqApplicationCore::instance(), SLOT(quickLaunch()));
399
400   // Find Plugin Dock Widgets
401   QList<QDockWidget*> currentDocks = aDesktop->findChildren<QDockWidget*>();
402   QList<QDockWidget*>::iterator i;
403   for (i = currentDocks.begin(); i != currentDocks.end(); ++i) {
404     if(!activeDocks.contains(*i)) {
405       myDockWidgets[*i] = false; // hidden by default
406       (*i)->hide();
407     }
408   }
409
410     // Find Plugin Menus
411     // [ABN] TODO: fix this - triggers a SEGFAULT at deactivation() time.
412 //    QList<QMenu*> currentMenus = aDesktop->findChildren<QMenu*>();
413 //    QList<QMenu*>::iterator im;
414 //    for (im = currentMenus.begin(); im != currentMenus.end(); ++im) {
415 //      if(!activeMenus.contains(*im)) {
416 //          QString s = (*im)->title();
417 //          std::cout << " MENU "<<  s.toStdString() << std::endl;
418 //          myMenus.append(*im);
419 //      }
420 //    }
421
422   PVViewer_ViewManager::ParaviewLoadConfigurations();
423   updateObjBrowser();
424
425   // Find created toolbars
426   QCoreApplication::processEvents();
427
428   QList<QToolBar*> allToolbars = aDesktop->findChildren<QToolBar*>();
429   foreach(QToolBar* aBar, allToolbars) {
430     if (!foreignToolbars.contains(aBar)) {
431       myToolbars[aBar] = true;
432       myToolbarBreaks[aBar] = false;
433       aBar->setVisible(false);
434       aBar->toggleViewAction()->setVisible(false);
435     }
436   }
437
438   updateMacros();
439  
440   SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr();
441   bool isStop = aResourceMgr->booleanValue( PARAVIS_MODULE_NAME, "stop_trace", false );
442   if(!isStop)
443     {
444       // Start a timer to schedule asap:
445       //  - the trace start
446       myInitTimer = new QTimer(aDesktop);
447       QObject::connect(myInitTimer, SIGNAL(timeout()), this, SLOT(onInitTimer()) );
448       myInitTimer->setSingleShot(true);
449       myInitTimer->start(0);
450
451       // Another timer to regularly push the trace onto the engine:
452       myPushTraceTimer = new QTimer(aDesktop);
453       QObject::connect(myPushTraceTimer, SIGNAL(timeout()), this, SLOT(onPushTraceTimer()) );
454       myPushTraceTimer->setSingleShot(false);
455       myPushTraceTimer->start(500);
456     }
457
458   this->VTKConnect = vtkEventQtSlotConnect::New();
459   
460   vtkProcessModule* pm = vtkProcessModule::GetProcessModule();
461   if(pm) {
462     vtkPVSession* pvs = dynamic_cast<vtkPVSession*>(pm->GetSession());
463     if(pvs) {
464       vtkPVProgressHandler* ph = pvs->GetProgressHandler();
465       if(ph) {
466           this->VTKConnect->Connect(ph, vtkCommand::StartEvent,
467                                     this, SLOT(onStartProgress()));
468           this->VTKConnect->Connect(ph, vtkCommand::EndEvent,
469                                     this, SLOT(onEndProgress()));
470       }
471     }
472   }
473 }
474
475 void PVGUI_Module::onStartProgress()
476 {
477   QApplication::setOverrideCursor(Qt::WaitCursor);
478 }
479
480 void PVGUI_Module::onEndProgress()
481 {
482   QApplication::restoreOverrideCursor();
483 }
484
485 void PVGUI_Module::onDataRepresentationUpdated() {
486   SalomeApp_Study* activeStudy = dynamic_cast<SalomeApp_Study*>(application()->activeStudy());
487   if(!activeStudy) return;
488   
489   activeStudy->Modified();
490 }
491
492 /*!
493   \brief Initialisation timer event - trace start up
494 */
495 void PVGUI_Module::onInitTimer()
496 {
497   startTrace();
498 }
499   
500 /*!
501   \brief Get list of embedded macros files
502 */
503 QStringList PVGUI_Module::getEmbeddedMacrosList()
504 {
505   QString aRootDir = getenv("PARAVIS_ROOT_DIR");
506
507   QString aSourcePath = aRootDir + "/bin/salome/Macro";
508
509   QStringList aFilter;
510   aFilter << "*.py";
511
512   QDir aSourceDir(aSourcePath);
513   QStringList aSourceFiles = aSourceDir.entryList(aFilter, QDir::Files);
514   QStringList aFullPathSourceFiles;
515   foreach (QString aMacrosName, aSourceFiles) {
516     aFullPathSourceFiles << aSourceDir.absoluteFilePath(aMacrosName);
517   }
518   return aFullPathSourceFiles;
519 }
520
521 void PVGUI_Module::updateMacros()
522 {
523   pqPythonManager* aPythonManager = pqPVApplicationCore::instance()->pythonManager();
524   if(!aPythonManager)  {
525     return;
526   }
527   
528   foreach (QString aStr, getEmbeddedMacrosList()) {
529     aPythonManager->addMacro(aStr);
530   }
531 }
532
533
534 /*!
535   \brief Get list of compliant dockable GUI elements
536   \param m map to be filled in ("type":"default_position")
537 */
538 void PVGUI_Module::windows( QMap<int, int>& m ) const
539 {
540   m.insert( LightApp_Application::WT_ObjectBrowser, Qt::LeftDockWidgetArea );
541   m.insert( LightApp_Application::WT_PyConsole, Qt::BottomDockWidgetArea );
542   // ParaView diagnostic output redirected here
543   m.insert( LightApp_Application::WT_LogWindow, Qt::BottomDockWidgetArea );
544 }
545
546 /*!
547   \brief Shows (toShow = true) or hides ParaView view window
548 */
549 void PVGUI_Module::showView( bool toShow )
550 {
551   LightApp_Application* anApp = getApp();
552   PVViewer_ViewManager* viewMgr =
553     dynamic_cast<PVViewer_ViewManager*>( anApp->getViewManager( PVViewer_Viewer::Type(), false ) );
554   if ( !viewMgr ) {
555     viewMgr = new PVViewer_ViewManager( anApp->activeStudy(), anApp->desktop(), anApp->logWindow() );
556     anApp->addViewManager( viewMgr );
557     connect( viewMgr, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
558              anApp, SLOT( onCloseView( SUIT_ViewManager* ) ) );
559   }
560
561   PVViewer_ViewWindow* pvWnd = dynamic_cast<PVViewer_ViewWindow*>( viewMgr->getActiveView() );
562   if ( !pvWnd ) {
563     pvWnd = dynamic_cast<PVViewer_ViewWindow*>( viewMgr->createViewWindow() );
564     // this also connects to the pvserver and instantiates relevant PV behaviors
565   }
566
567   pvWnd->setShown( toShow );
568   if ( toShow ) pvWnd->setFocus();
569 }
570
571 /*!
572   \brief Slot to show help for proxy.
573 */
574 void PVGUI_Module::showHelpForProxy( const QString& groupname, const QString& proxyname )
575 {
576   pqHelpReaction::showProxyHelp(groupname, proxyname);
577 }
578
579
580 /*!
581   \brief Slot to show the waiting state.
582 */
583 void PVGUI_Module::onPreAccept()
584 {
585   getApp()->desktop()->statusBar()->showMessage(tr("STB_PREACCEPT"));
586   QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
587 }
588
589 /*!
590   \brief Slot to show the ready state.
591 */
592 void PVGUI_Module::onPostAccept()
593 {
594   getApp()->desktop()->statusBar()->showMessage(tr("STB_POSTACCEPT"), 2000);
595   QTimer::singleShot(0, this, SLOT(endWaitCursor()));
596 }
597
598 /*!
599   \brief Slot to switch off wait cursor.
600 */
601 void PVGUI_Module::endWaitCursor()
602 {
603   QApplication::restoreOverrideCursor();
604 }
605
606 static void ParavisMessageOutput(QtMsgType type, const char *msg)
607 {
608   switch(type)
609     {
610   case QtDebugMsg:
611     vtkOutputWindow::GetInstance()->DisplayText(msg);
612     break;
613   case QtWarningMsg:
614     vtkOutputWindow::GetInstance()->DisplayErrorText(msg);
615     break;
616   case QtCriticalMsg:
617     vtkOutputWindow::GetInstance()->DisplayErrorText(msg);
618     break;
619   case QtFatalMsg:
620     vtkOutputWindow::GetInstance()->DisplayErrorText(msg);
621     break;
622     }
623 }
624
625 /*!
626   \brief Activate module.
627   \param study current study
628   \return \c true if activaion is done successfully or 0 to prevent
629   activation on error
630 */
631 bool PVGUI_Module::activateModule( SUIT_Study* study )
632 {
633   myOldMsgHandler = qInstallMsgHandler(ParavisMessageOutput);
634   
635   SUIT_ExceptionHandler::addCleanUpRoutine( paravisCleanUp );
636
637   storeCommonWindowsState();
638
639   bool isDone = LightApp_Module::activateModule( study );
640   if ( !isDone ) return false;
641
642   showView( true );
643   if ( mySourcesMenuId != -1 ) menuMgr()->show(mySourcesMenuId);
644   if ( myFiltersMenuId != -1 ) menuMgr()->show(myFiltersMenuId);
645   if ( myMacrosMenuId != -1 ) menuMgr()->show(myMacrosMenuId);
646   if ( myToolbarsMenuId != -1 ) menuMgr()->show(myToolbarsMenuId);
647
648   // Update the various menus with the content pre-loaded in myGuiElements
649 //  QMenu* srcMenu = menuMgr()->findMenu( mySourcesMenuId );
650 //  myGuiElements->updateSourcesMenu(srcMenu);
651 //  QMenu* filtMenu = menuMgr()->findMenu( myFiltersMenuId );
652 //  myGuiElements->updateFiltersMenu(filtMenu);
653 //  QMenu* macMenu = menuMgr()->findMenu( myMacrosMenuId );
654 //  myGuiElements->updateMacrosMenu(macMenu);
655
656   setMenuShown( true );
657   setToolShown( true );
658
659   restoreDockWidgetsState();
660
661   QMenu* aMenu = menuMgr()->findMenu( myRecentMenuId );
662   if(aMenu) {
663     QList<QAction*> anActns = aMenu->actions();
664     for (int i = 0; i < anActns.size(); ++i) {
665       QAction* a = anActns.at(i);
666       if(a)
667         a->setVisible(true);
668     }
669   }
670
671   QList<QMenu*>::iterator it;
672   for (it = myMenus.begin(); it != myMenus.end(); ++it) {
673     QAction* a = (*it)->menuAction();
674     if(a)
675       a->setVisible(true);
676   }
677
678   if ( myRecentMenuId != -1 ) menuMgr()->show(myRecentMenuId);
679
680   ClientFindOrCreateParavisComponent(PARAVIS::GetCStudy(this));
681
682   return isDone;
683 }
684
685
686 /*!
687   \brief Deactivate module.
688   \param study current study
689   \return \c true if deactivaion is done successfully or 0 to prevent
690   deactivation on error
691 */
692 bool PVGUI_Module::deactivateModule( SUIT_Study* study )
693 {
694   MESSAGE("PARAVIS deactivation ...")
695
696   QMenu* aMenu = menuMgr()->findMenu( myRecentMenuId );
697   if(aMenu) {
698     QList<QAction*> anActns = aMenu->actions();
699     for (int i = 0; i < anActns.size(); ++i) {
700       QAction* a = anActns.at(i);
701       if(a)
702         a->setVisible(false);
703     }
704   }
705
706   QList<QMenu*>::iterator it;
707   for (it = myMenus.begin(); it != myMenus.end(); ++it) {
708     QAction* a = (*it)->menuAction();
709     if(a)
710       a->setVisible(false);
711   }
712
713   QList<QDockWidget*> aStreamingViews = application()->desktop()->findChildren<QDockWidget*>("pqStreamingControls");
714   foreach(QDockWidget* aView, aStreamingViews) {
715     if (!myDockWidgets.contains(aView))
716       myDockWidgets[aView] = aView->isVisible();
717   }
718
719   /*if (pqImplementation::helpWindow) {
720     pqImplementation::helpWindow->hide();
721     }*/
722   showView( false );
723   // hide menus
724   menuMgr()->hide(myRecentMenuId);
725   menuMgr()->hide(mySourcesMenuId);
726   menuMgr()->hide(myFiltersMenuId);
727   menuMgr()->hide(myMacrosMenuId);
728   menuMgr()->hide(myToolbarsMenuId);
729   setMenuShown( false );
730   setToolShown( false );
731
732   saveDockWidgetsState();
733
734   SUIT_ExceptionHandler::removeCleanUpRoutine( paravisCleanUp );
735
736   if (myOldMsgHandler)
737     qInstallMsgHandler(myOldMsgHandler);
738
739   restoreCommonWindowsState();
740   
741   return LightApp_Module::deactivateModule( study );
742 }
743
744
745 /*!
746   \brief Called when application is closed.
747
748   Process finalize application functionality from ParaView in order to save server settings
749   and nullify application pointer if the application is being closed.
750
751   \param theApp application
752 */
753 void PVGUI_Module::onApplicationClosed( SUIT_Application* theApp )
754 {
755   PVViewer_ViewManager::ParaviewCleanup();
756
757   int aAppsNb = SUIT_Session::session()->applications().size();
758   if (aAppsNb == 1) {
759     deleteTemporaryFiles();
760   }
761   CAM_Module::onApplicationClosed(theApp);
762 }
763
764
765 /*!
766   \brief Deletes temporary files created during import operation from VISU
767 */
768 void PVGUI_Module::deleteTemporaryFiles()
769 {
770   foreach(QString aFile, myTemporaryFiles) {
771     if (QFile::exists(aFile)) {
772       QFile::remove(aFile);
773     }
774   }
775 }
776
777
778 /*!
779   \brief Called when study is closed.
780
781   Removes data model from the \a study.
782
783   \param study study being closed
784 */
785 void PVGUI_Module::studyClosed(SUIT_Study* study)
786 {
787   clearParaviewState();
788
789   LightApp_Module::studyClosed(study);
790 }
791
792 /*!
793   \brief Called when study is opened.
794 */
795 void PVGUI_Module::onModelOpened()
796 {
797   _PTR(Study) studyDS = PARAVIS::GetCStudy(this);
798   if(!studyDS) {
799     return;
800   }
801
802   _PTR(SComponent) paravisComp =
803     studyDS->FindComponent(PARAVIS_MODULE_NAME);
804   if(!paravisComp) {
805     return;
806   }
807
808   _PTR(ChildIterator) anIter(studyDS->NewChildIterator(paravisComp));
809   for (; anIter->More(); anIter->Next()) {
810     _PTR(SObject) aSObj = anIter->Value();
811     _PTR(GenericAttribute) anAttr;
812     if (!aSObj->FindAttribute(anAttr, "AttributeLocalID")) {
813       continue;
814     }
815     _PTR(AttributeLocalID) anID(anAttr);
816     if (anID->Value() == PVSTATEID) {
817       myStateCounter++;
818     }
819   }
820 }
821
822 /*!
823 \brief Returns IOR of current engine
824 */
825 QString PVGUI_Module::engineIOR() const
826 {
827   CORBA::String_var anIOR = GetCPPEngine()->GetIOR();
828   return QString(anIOR.in());
829 }
830
831 /*!
832   \brief Open file of format supported by ParaView
833 */
834 void PVGUI_Module::openFile(const char* theName)
835 {
836   QStringList aFiles;
837   aFiles<<theName;
838   pqLoadDataReaction::loadData(aFiles);
839 }
840
841 /**!
842  * Start trace invoking the newly introduced C++ API (PV 4.2)
843  * (inspired from pqTraceReaction::start())
844  */
845 void PVGUI_Module::startTrace()
846 {
847   vtkSMSessionProxyManager* pxm = pqActiveObjects::instance().activeServer()->proxyManager();
848
849   vtkSmartPointer<vtkSMProxy> proxy;
850   proxy.TakeReference(pxm->NewProxy("pythontracing", "PythonTraceOptions"));
851   if (proxy)
852     {
853       vtkNew<vtkSMParaViewPipelineController> controller;
854       controller->InitializeProxy(proxy);
855     }
856   vtkSMTrace* trace = vtkSMTrace::StartTrace();
857   if (proxy)
858     {
859       // Set manually the properties entered via the dialog box poping-up when requiring
860       // a trace start in PV4.2 (trace options)
861       trace->SetPropertiesToTraceOnCreate(vtkSMTrace::RECORD_USER_MODIFIED_PROPERTIES);
862       trace->SetFullyTraceSupplementalProxies(false);
863     }
864 }
865
866 void PVGUI_Module::stopTrace()
867 {
868   vtkSMTrace::StopTrace();
869 }
870
871 void PVGUI_Module::executeScript(const char *script)
872 {
873 #ifndef WNT
874   pqPythonManager* manager = qobject_cast<pqPythonManager*>(
875                              pqApplicationCore::instance()->manager("PYTHON_MANAGER"));
876   if (manager)  {
877     pqPythonDialog* pyDiag = manager->pythonShellDialog();
878     if (pyDiag) {
879       pyDiag->runString(script);  
880       }
881     }
882 #endif
883 }
884
885 ///**
886 // *  Debug function printing out the given interpreter's execution context
887 // */
888 //void printInterpContext(PyInterp_Interp * interp )
889 //{
890 //  // Extract __smtraceString from interpreter's context
891 //  const PyObject* ctxt = interp->getExecutionContext();
892 //
893 //  PyObject* lst = PyDict_Keys((PyObject *)ctxt);
894 //  Py_ssize_t siz = PyList_GET_SIZE(lst);
895 //  for (Py_ssize_t i = 0; i < siz; i++)
896 //    {
897 //      PyObject * elem = PyList_GetItem(lst, i);
898 //      if (PyString_Check(elem))
899 //        {
900 //          std::cout << "At pos:" << i << ", " << PyString_AsString(elem) << std::endl;
901 //        }
902 //      else
903 //        std::cout << "At pos:" << i << ", not a string!" << std::endl;
904 //    }
905 //  Py_XDECREF(lst);
906 //}
907
908 /*!
909   \brief Returns trace string
910 */
911 static const QString MYReplaceStr("paraview.simple");
912 QString PVGUI_Module::getTraceString()
913 {
914   vtkSMTrace *tracer = vtkSMTrace::GetActiveTracer();
915   if (!tracer) // trace is not started
916     return QString("");
917
918   QString traceString(tracer->GetCurrentTrace());
919   std::stringstream nl; nl << std::endl; // surely there is some Qt trick to do that in a portable way??
920   QString end_line(nl.str().c_str());
921   // 'import pvsimple' is necessary to fix the first call to DisableFirstRenderCamera in the paraview trace
922   // 'ShowParaviewView()' ensure there is an opened viewing window (otherwise SEGFAULT!)
923   traceString = "import pvsimple" + end_line +
924                 "pvsimple.ShowParaviewView()" + end_line + traceString;
925
926   // Replace import "paraview.simple" by "pvsimple"
927   if ((!traceString.isNull()) && traceString.length() != 0) {
928     int aPos = traceString.indexOf(MYReplaceStr);
929     while (aPos != -1) {
930       traceString = traceString.replace(aPos, MYReplaceStr.length(), "pvsimple");
931       aPos = traceString.indexOf(MYReplaceStr, aPos);
932     }
933   }
934
935   return traceString;
936 }
937
938 /*!
939   \brief Saves trace string to disk file
940 */
941 void PVGUI_Module::saveTrace(const char* theName)
942 {
943   QFile file(theName);
944   if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
945     MESSAGE( "Could not open file:" << theName );
946     return;
947   }
948   QTextStream out(&file);
949   out << getTraceString();
950   file.close();
951 }
952
953 /*!
954   \brief Saves ParaView state to a disk file
955 */
956 void PVGUI_Module::saveParaviewState(const char* theFileName)
957 {
958   pqApplicationCore::instance()->saveState(theFileName);
959 }
960
961 /*!
962   \brief Delete all objects for Paraview Pipeline Browser
963 */
964 void PVGUI_Module::clearParaviewState()
965 {
966   QAction* deleteAllAction = action(DeleteAllId);
967   if (deleteAllAction) {
968     deleteAllAction->activate(QAction::Trigger);
969   }
970 }
971
972 /*!
973   \brief Restores ParaView state from a disk file
974
975   If toClear == true, the current ojects will be deleted
976 */
977 void PVGUI_Module::loadParaviewState(const char* theFileName)
978 {
979   pqApplicationCore::instance()->loadState(theFileName, getActiveServer());
980 }
981
982 /*!
983   \brief Returns current active ParaView server
984 */
985 pqServer* PVGUI_Module::getActiveServer()
986 {
987   return pqApplicationCore::instance()->getActiveServer();
988 }
989
990
991 /*!
992   \brief Creates PARAVIS preference pane 
993 */
994 void PVGUI_Module::createPreferences()
995 {
996   // Paraview settings tab
997   int aParaViewSettingsTab = addPreference( tr( "TIT_PVIEWSETTINGS" ) );
998
999   setPreferenceProperty(aParaViewSettingsTab, "stretch", false );
1000   int aPanel = addPreference(QString(), aParaViewSettingsTab, LightApp_Preferences::UserDefined, PARAVIS_MODULE_NAME, "");
1001
1002   setPreferenceProperty(aPanel, "content", (qint64)(new PVGUI_ParaViewSettingsPane()));
1003
1004   // Paravis settings tab
1005   int aParaVisSettingsTab = addPreference( tr( "TIT_PVISSETTINGS" ) );
1006   addPreference( tr( "PREF_STOP_TRACE" ), aParaVisSettingsTab, LightApp_Preferences::Bool, PARAVIS_MODULE_NAME, "stop_trace");
1007
1008   addPreference( tr( "PREF_NO_EXT_PVSERVER" ), aParaVisSettingsTab, LightApp_Preferences::Bool, PARAVIS_MODULE_NAME, "no_ext_pv_server");
1009
1010   int aSaveType = addPreference(tr( "PREF_SAVE_TYPE_LBL" ), aParaVisSettingsTab,
1011                                 LightApp_Preferences::Selector,
1012                                 PARAVIS_MODULE_NAME, "savestate_type");
1013   QList<QVariant> aIndices;
1014   QStringList aStrings;
1015   aIndices<<0<<1<<2;
1016   aStrings<<tr("PREF_SAVE_TYPE_0");
1017   aStrings<<tr("PREF_SAVE_TYPE_1");
1018   aStrings<<tr("PREF_SAVE_TYPE_2");
1019   setPreferenceProperty(aSaveType, "strings", aStrings);
1020   setPreferenceProperty(aSaveType, "indexes", aIndices);
1021 }
1022
1023 /*!
1024   \brief Creates ParaViS context menu popup
1025 */
1026 void PVGUI_Module::contextMenuPopup(const QString& theClient, QMenu* theMenu, QString& theTitle)
1027 {
1028   LightApp_Module::contextMenuPopup(theClient, theMenu, theTitle);
1029
1030   // Check if we are in Object Browser
1031   SUIT_DataBrowser* ob = getApp()->objectBrowser();
1032   bool isOBClient = (ob && theClient == ob->popupClientType());
1033   if (!isOBClient) {
1034     return;
1035   }
1036
1037   // Get list of selected objects
1038   LightApp_SelectionMgr* aSelectionMgr = getApp()->selectionMgr();
1039   SALOME_ListIO aListIO;
1040   aSelectionMgr->selectedObjects(aListIO);
1041   if (aListIO.Extent() == 1 && aListIO.First()->hasEntry()) {
1042     QString entry = QString(aListIO.First()->getEntry());
1043
1044     // Get active study
1045     SalomeApp_Study* activeStudy =
1046       dynamic_cast<SalomeApp_Study*>(getApp()->activeStudy());
1047     if(!activeStudy) {
1048       return;
1049     }
1050
1051     // Get SALOMEDS client study
1052     _PTR(Study) studyDS = activeStudy->studyDS();
1053     if(!studyDS) {
1054       return;
1055     }
1056
1057     QString paravisDataType(PARAVIS_MODULE_NAME);
1058     if(activeStudy && activeStudy->isComponent(entry) &&
1059        activeStudy->componentDataType(entry) == paravisDataType) {
1060       // ParaViS module object
1061       theMenu->addSeparator();
1062       theMenu->addAction(action(SaveStatePopupId));
1063     }
1064     else {
1065       // Try to get state object
1066       _PTR(SObject) stateSObj =
1067           studyDS->FindObjectID(entry.toLatin1().constData());
1068       if (!stateSObj) {
1069           return;
1070       }
1071
1072       // Check local id
1073       _PTR(GenericAttribute) anAttr;
1074       if (!stateSObj->FindAttribute(anAttr, "AttributeLocalID")) {
1075           return;
1076       }
1077
1078       _PTR(AttributeLocalID) anID(anAttr);
1079
1080       if (anID->Value() == PVSTATEID) {
1081         // Paraview state object
1082         theMenu->addSeparator();
1083         theMenu->addAction(action(AddStatePopupId));
1084         theMenu->addAction(action(CleanAndAddStatePopupId));
1085         theMenu->addSeparator();
1086         theMenu->addAction(action(ParaVisRenameId));
1087         theMenu->addAction(action(ParaVisDeleteId));
1088       }
1089     }
1090   }
1091 }
1092
1093 /*!
1094   \brief. Show ParaView python trace.
1095 */
1096 void PVGUI_Module::onShowTrace()
1097 {
1098   if (!myTraceWindow) {
1099     myTraceWindow = new pqPythonScriptEditor(getApp()->desktop());
1100   }
1101   myTraceWindow->setText(getTraceString());
1102   myTraceWindow->show();
1103   myTraceWindow->raise();
1104   myTraceWindow->activateWindow();
1105 }
1106
1107
1108 /*!
1109   \brief. Re-initialize ParaView python trace.
1110 */
1111 void PVGUI_Module::onRestartTrace()
1112 {
1113   stopTrace();
1114   startTrace();
1115 }
1116
1117 /*!
1118   \brief Save state under the module root object.
1119 */
1120 void PVGUI_Module::onSaveMultiState()
1121 {
1122   // Create state study object
1123   
1124   // Get SALOMEDS client study
1125   _PTR(Study) studyDS = PARAVIS::GetCStudy(this);
1126   if(!studyDS) {
1127     return;
1128   }
1129
1130   _PTR(SComponent) paravisComp = 
1131       studyDS->FindComponent(PARAVIS_MODULE_NAME);
1132   if(!paravisComp) {
1133     return;
1134   }
1135
1136   // Unlock the study if it is locked
1137   bool isLocked = studyDS->GetProperties()->IsLocked();
1138   if (isLocked) {
1139     studyDS->GetProperties()->SetLocked(false);
1140   }
1141   
1142   QString stateName = tr("SAVED_PARAVIEW_STATE_NAME") + 
1143     QString::number(myStateCounter + 1);
1144
1145   _PTR(StudyBuilder) studyBuilder = studyDS->NewBuilder();
1146   _PTR(SObject) newSObj = studyBuilder->NewObject(paravisComp);
1147
1148   // Set name
1149   _PTR(GenericAttribute) anAttr;
1150   anAttr = studyBuilder->FindOrCreateAttribute(newSObj, "AttributeName");
1151   _PTR(AttributeName) nameAttr(anAttr);
1152   
1153   nameAttr->SetValue(stateName.toLatin1().constData());
1154
1155   // Set local id
1156   anAttr = studyBuilder->FindOrCreateAttribute(newSObj, "AttributeLocalID");
1157   _PTR(AttributeLocalID) localIdAttr(anAttr);
1158   
1159   localIdAttr->SetValue(PVSTATEID);
1160
1161   // Set file name
1162   QString stateEntry = QString::fromStdString(newSObj->GetID());
1163  
1164   // File name for state saving
1165   QString tmpDir = QString::fromStdString(SALOMEDS_Tool::GetTmpDir());
1166   QString fileName = QString("%1_paravisstate:%2").arg(tmpDir, stateEntry);
1167
1168   anAttr = studyBuilder->FindOrCreateAttribute(newSObj, "AttributeString");
1169   _PTR(AttributeString) stringAttr(anAttr);
1170   
1171   stringAttr->SetValue(fileName.toLatin1().constData());
1172
1173   // Lock the study back if necessary
1174   if (isLocked) {
1175     studyDS->GetProperties()->SetLocked(true);
1176   }
1177   
1178   // Save state
1179   saveParaviewState(fileName.toLatin1().constData());
1180   myTemporaryFiles.append(fileName);
1181   
1182   // Increment the counter
1183   myStateCounter++;
1184
1185   updateObjBrowser();
1186 }
1187
1188 /*!
1189   \brief Restore the selected state by merging with the current one.
1190 */
1191 void PVGUI_Module::onAddState()
1192 {
1193   loadSelectedState(false);
1194 }
1195
1196 /*!
1197   \brief Clean the current state and restore the selected one.
1198 */
1199 void PVGUI_Module::onCleanAddState()
1200 {
1201   loadSelectedState(true);
1202 }
1203
1204 /*!
1205   \brief Rename the selected object.
1206 */
1207 void PVGUI_Module::onRename()
1208 {
1209   LightApp_SelectionMgr* aSelectionMgr = getApp()->selectionMgr();
1210   SALOME_ListIO aListIO;
1211   aSelectionMgr->selectedObjects(aListIO);
1212   
1213   if (aListIO.Extent() == 1 && aListIO.First()->hasEntry()) {
1214     std::string entry = aListIO.First()->getEntry();
1215     
1216     // Get SALOMEDS client study 
1217     _PTR(Study) studyDS = PARAVIS::GetCStudy(this);
1218     if(!studyDS) {
1219       return;
1220     }
1221     
1222     // Unlock the study if it is locked
1223     bool isLocked = studyDS->GetProperties()->IsLocked();
1224     if (isLocked) {
1225       studyDS->GetProperties()->SetLocked(false);
1226     }
1227     
1228     // Rename the selected state object
1229     _PTR(SObject) stateSObj = studyDS->FindObjectID(entry);
1230     if (!stateSObj) {
1231       return;
1232     }
1233     
1234     _PTR(GenericAttribute) anAttr;
1235     if (stateSObj->FindAttribute(anAttr, "AttributeName")) {
1236       _PTR(AttributeName) nameAttr (anAttr);
1237       QString newName = 
1238           LightApp_NameDlg::getName(getApp()->desktop(), nameAttr->Value().c_str());
1239       if (!newName.isEmpty()) {
1240         nameAttr->SetValue(newName.toLatin1().constData());
1241         aListIO.First()->setName(newName.toLatin1().constData());
1242       }
1243     }
1244     
1245     // Lock the study back if necessary
1246     if (isLocked) {
1247       studyDS->GetProperties()->SetLocked(true);
1248     }
1249     
1250     // Update object browser
1251     updateObjBrowser();
1252     
1253   }
1254 }
1255
1256 /*!
1257   \brief Delete the selected objects.
1258 */
1259 void PVGUI_Module::onDelete()
1260 {
1261   LightApp_SelectionMgr* aSelectionMgr = getApp()->selectionMgr();
1262   SALOME_ListIO aListIO;
1263   aSelectionMgr->selectedObjects(aListIO);
1264   
1265   if (aListIO.Extent() == 1 && aListIO.First()->hasEntry()) {
1266     std::string entry = aListIO.First()->getEntry();
1267     
1268     // Get SALOMEDS client study 
1269     _PTR(Study) studyDS = PARAVIS::GetCStudy(this);
1270     if(!studyDS) {
1271       return;
1272     }
1273     
1274     // Unlock the study if it is locked
1275     bool isLocked = studyDS->GetProperties()->IsLocked();
1276     if (isLocked) {
1277       studyDS->GetProperties()->SetLocked(false);
1278     }
1279     
1280     // Remove the selected state from the study
1281     _PTR(StudyBuilder) studyBuilder = studyDS->NewBuilder();
1282     _PTR(SObject) stateSObj = studyDS->FindObjectID(entry);
1283     studyBuilder->RemoveObject(stateSObj);
1284     
1285     // Lock the study back if necessary
1286     if (isLocked) {
1287       studyDS->GetProperties()->SetLocked(true);
1288     }
1289     
1290     // Update object browser
1291     updateObjBrowser();
1292   }
1293 }
1294
1295 void PVGUI_Module::onPushTraceTimer()
1296 {
1297   //MESSAGE("onPushTraceTimer(): Pushing trace to engine...");
1298   GetEngine()->PutPythonTraceStringToEngine(getTraceString().toStdString().c_str());
1299 }
1300
1301 /*!
1302   \brief Discover help project files from the resources.
1303   \return name of the help file. 
1304 */
1305 QString PVGUI_Module::getHelpFileName() {
1306   QString aPVHome(getenv("PVHOME"));
1307   if (aPVHome.isNull()) {
1308     qWarning("Wariable PVHOME is not defined");
1309     return QString();
1310   }
1311   QChar aSep = QDir::separator();
1312   //PARAVIEW_VERSION from the vtkPVConfig.h file
1313   QString aFileName =  aPVHome + aSep + "share" + aSep + "doc" + aSep + "paraview-"+ PARAVIEW_VERSION + aSep + "paraview.qch";
1314   return aFileName;
1315 }
1316
1317
1318 /*!
1319   \brief Load selected paraview state
1320
1321   If toClear == true, the current state will be cleared
1322 */
1323 void PVGUI_Module::loadSelectedState(bool toClear)
1324 {
1325   QString fileName;
1326
1327   LightApp_SelectionMgr* aSelectionMgr = getApp()->selectionMgr();
1328   SALOME_ListIO aListIO;
1329   aSelectionMgr->selectedObjects(aListIO);
1330   
1331   if (aListIO.Extent() == 1 && aListIO.First()->hasEntry()) {
1332     std::string entry = aListIO.First()->getEntry();
1333     
1334     // Get SALOMEDS client study 
1335     _PTR(Study) studyDS = PARAVIS::GetCStudy(this);
1336     if(!studyDS) {
1337       return;
1338     }
1339
1340     // Check local id
1341     _PTR(SObject) stateSObj = studyDS->FindObjectID(entry);
1342     _PTR(GenericAttribute) anAttr;
1343     if (!stateSObj->FindAttribute(anAttr, "AttributeLocalID")) {
1344       return;
1345     }
1346     _PTR(AttributeLocalID) anID(anAttr);
1347     if (!anID->Value() == PVSTATEID) {
1348       return;
1349     }
1350
1351     // Get state file name
1352     if (stateSObj->FindAttribute(anAttr, "AttributeString")) {
1353       _PTR(AttributeString) aStringAttr(anAttr);
1354       QString stringValue(aStringAttr->Value().c_str());
1355
1356       if (QFile::exists(stringValue)) {
1357           fileName = stringValue;
1358       }
1359     }
1360   }
1361   
1362   if (!fileName.isEmpty()) {
1363     if (toClear) {
1364       clearParaviewState();
1365     }
1366
1367     loadParaviewState(fileName.toLatin1().constData());
1368   } 
1369   else {
1370     SUIT_MessageBox::critical(getApp()->desktop(),
1371                               tr("ERR_ERROR"),
1372                               tr("ERR_STATE_CANNOT_BE_RESTORED"));
1373   }
1374 }
1375
1376 /*!
1377   \fn CAM_Module* createModule();
1378   \brief Export module instance (factory function).
1379   \return new created instance of the module
1380 */
1381
1382 #ifdef WNT
1383 #define PVGUI_EXPORT __declspec(dllexport)
1384 #else   // WNT
1385 #define PVGUI_EXPORT
1386 #endif  // WNT
1387
1388 extern "C" {
1389
1390   bool flag = false;
1391   PVGUI_EXPORT CAM_Module* createModule() {
1392     return new PVGUI_Module();
1393   }
1394   
1395   PVGUI_EXPORT char* getModuleVersion() {
1396     return (char*)PARAVIS_VERSION_STR;
1397   }
1398 }