]> SALOME platform Git repositories - modules/paravis.git/blob - src/PVGUI/PVGUI_Module.cxx
Salome HOME
Fixing menus.
[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   PVViewer_ViewManager::ConnectToExternalPVServer(aDesktop);
384
385   pvCreateActions();
386   pvCreateToolBars();
387   pvCreateMenus();
388
389   QList<QDockWidget*> activeDocks = aDesktop->findChildren<QDockWidget*>();
390   QList<QMenu*> activeMenus = aDesktop->findChildren<QMenu*>();
391
392   // Setup quick-launch shortcuts.
393   QShortcut *ctrlSpace = new QShortcut(Qt::CTRL + Qt::Key_Space, aDesktop);
394   QObject::connect(ctrlSpace, SIGNAL(activated()),
395     pqApplicationCore::instance(), SLOT(quickLaunch()));
396
397   // Find Plugin Dock Widgets
398   QList<QDockWidget*> currentDocks = aDesktop->findChildren<QDockWidget*>();
399   QList<QDockWidget*>::iterator i;
400   for (i = currentDocks.begin(); i != currentDocks.end(); ++i) {
401     if(!activeDocks.contains(*i)) {
402       myDockWidgets[*i] = false; // hidden by default
403       (*i)->hide();
404     }
405   }
406
407     // Find Plugin Menus
408     // [ABN] TODO: fix this - triggers a SEGFAULT at deactivation() time.
409 //    QList<QMenu*> currentMenus = aDesktop->findChildren<QMenu*>();
410 //    QList<QMenu*>::iterator im;
411 //    for (im = currentMenus.begin(); im != currentMenus.end(); ++im) {
412 //      if(!activeMenus.contains(*im)) {
413 //          QString s = (*im)->title();
414 //          std::cout << " MENU "<<  s.toStdString() << std::endl;
415 //          myMenus.append(*im);
416 //      }
417 //    }
418
419   PVViewer_ViewManager::ParaviewLoadConfigurations();
420   updateObjBrowser();
421
422   // Find created toolbars
423   QCoreApplication::processEvents();
424
425   QList<QToolBar*> allToolbars = aDesktop->findChildren<QToolBar*>();
426   foreach(QToolBar* aBar, allToolbars) {
427     if (!foreignToolbars.contains(aBar)) {
428       myToolbars[aBar] = true;
429       myToolbarBreaks[aBar] = false;
430       aBar->setVisible(false);
431       aBar->toggleViewAction()->setVisible(false);
432     }
433   }
434
435   updateMacros();
436  
437   SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr();
438   bool isStop = aResourceMgr->booleanValue( PARAVIS_MODULE_NAME, "stop_trace", false );
439   if(!isStop)
440     {
441       // Start a timer to schedule asap:
442       //  - the trace start
443       myInitTimer = new QTimer(aDesktop);
444       QObject::connect(myInitTimer, SIGNAL(timeout()), this, SLOT(onInitTimer()) );
445       myInitTimer->setSingleShot(true);
446       myInitTimer->start(0);
447
448       // Another timer to regularly push the trace onto the engine:
449       myPushTraceTimer = new QTimer(aDesktop);
450       QObject::connect(myPushTraceTimer, SIGNAL(timeout()), this, SLOT(onPushTraceTimer()) );
451       myPushTraceTimer->setSingleShot(false);
452       myPushTraceTimer->start(500);
453     }
454
455   this->VTKConnect = vtkEventQtSlotConnect::New();
456   
457   vtkProcessModule* pm = vtkProcessModule::GetProcessModule();
458   if(pm) {
459     vtkPVSession* pvs = dynamic_cast<vtkPVSession*>(pm->GetSession());
460     if(pvs) {
461       vtkPVProgressHandler* ph = pvs->GetProgressHandler();
462       if(ph) {
463           this->VTKConnect->Connect(ph, vtkCommand::StartEvent,
464                                     this, SLOT(onStartProgress()));
465           this->VTKConnect->Connect(ph, vtkCommand::EndEvent,
466                                     this, SLOT(onEndProgress()));
467       }
468     }
469   }
470 }
471
472 void PVGUI_Module::onStartProgress()
473 {
474   QApplication::setOverrideCursor(Qt::WaitCursor);
475 }
476
477 void PVGUI_Module::onEndProgress()
478 {
479   QApplication::restoreOverrideCursor();
480 }
481
482 void PVGUI_Module::onDataRepresentationUpdated() {
483   SalomeApp_Study* activeStudy = dynamic_cast<SalomeApp_Study*>(application()->activeStudy());
484   if(!activeStudy) return;
485   
486   activeStudy->Modified();
487 }
488
489 /*!
490   \brief Initialisation timer event - trace start up
491 */
492 void PVGUI_Module::onInitTimer()
493 {
494   startTrace();
495 }
496   
497 /*!
498   \brief Get list of embedded macros files
499 */
500 QStringList PVGUI_Module::getEmbeddedMacrosList()
501 {
502   QString aRootDir = getenv("PARAVIS_ROOT_DIR");
503
504   QString aSourcePath = aRootDir + "/bin/salome/Macro";
505
506   QStringList aFilter;
507   aFilter << "*.py";
508
509   QDir aSourceDir(aSourcePath);
510   QStringList aSourceFiles = aSourceDir.entryList(aFilter, QDir::Files);
511   QStringList aFullPathSourceFiles;
512   foreach (QString aMacrosName, aSourceFiles) {
513     aFullPathSourceFiles << aSourceDir.absoluteFilePath(aMacrosName);
514   }
515   return aFullPathSourceFiles;
516 }
517
518 void PVGUI_Module::updateMacros()
519 {
520   pqPythonManager* aPythonManager = pqPVApplicationCore::instance()->pythonManager();
521   if(!aPythonManager)  {
522     return;
523   }
524   
525   foreach (QString aStr, getEmbeddedMacrosList()) {
526     aPythonManager->addMacro(aStr);
527   }
528 }
529
530
531 /*!
532   \brief Get list of compliant dockable GUI elements
533   \param m map to be filled in ("type":"default_position")
534 */
535 void PVGUI_Module::windows( QMap<int, int>& m ) const
536 {
537   m.insert( LightApp_Application::WT_ObjectBrowser, Qt::LeftDockWidgetArea );
538   m.insert( LightApp_Application::WT_PyConsole, Qt::BottomDockWidgetArea );
539   // ParaView diagnostic output redirected here
540   m.insert( LightApp_Application::WT_LogWindow, Qt::BottomDockWidgetArea );
541 }
542
543 /*!
544   \brief Shows (toShow = true) or hides ParaView view window
545 */
546 void PVGUI_Module::showView( bool toShow )
547 {
548   LightApp_Application* anApp = getApp();
549   PVViewer_ViewManager* viewMgr =
550     dynamic_cast<PVViewer_ViewManager*>( anApp->getViewManager( PVViewer_Viewer::Type(), false ) );
551   if ( !viewMgr ) {
552     viewMgr = new PVViewer_ViewManager( anApp->activeStudy(), anApp->desktop(), anApp->logWindow() );
553     anApp->addViewManager( viewMgr );
554     connect( viewMgr, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
555              anApp, SLOT( onCloseView( SUIT_ViewManager* ) ) );
556   }
557
558   PVViewer_ViewWindow* pvWnd = dynamic_cast<PVViewer_ViewWindow*>( viewMgr->getActiveView() );
559   if ( !pvWnd ) {
560     pvWnd = dynamic_cast<PVViewer_ViewWindow*>( viewMgr->createViewWindow() );
561     // this also connects to the pvserver and instantiates relevant PV behaviors
562   }
563
564   pvWnd->setShown( toShow );
565   if ( toShow ) pvWnd->setFocus();
566 }
567
568 /*!
569   \brief Slot to show help for proxy.
570 */
571 void PVGUI_Module::showHelpForProxy( const QString& groupname, const QString& proxyname )
572 {
573   pqHelpReaction::showProxyHelp(groupname, proxyname);
574 }
575
576
577 /*!
578   \brief Slot to show the waiting state.
579 */
580 void PVGUI_Module::onPreAccept()
581 {
582   getApp()->desktop()->statusBar()->showMessage(tr("STB_PREACCEPT"));
583   QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
584 }
585
586 /*!
587   \brief Slot to show the ready state.
588 */
589 void PVGUI_Module::onPostAccept()
590 {
591   getApp()->desktop()->statusBar()->showMessage(tr("STB_POSTACCEPT"), 2000);
592   QTimer::singleShot(0, this, SLOT(endWaitCursor()));
593 }
594
595 /*!
596   \brief Slot to switch off wait cursor.
597 */
598 void PVGUI_Module::endWaitCursor()
599 {
600   QApplication::restoreOverrideCursor();
601 }
602
603 static void ParavisMessageOutput(QtMsgType type, const char *msg)
604 {
605   switch(type)
606     {
607   case QtDebugMsg:
608     vtkOutputWindow::GetInstance()->DisplayText(msg);
609     break;
610   case QtWarningMsg:
611     vtkOutputWindow::GetInstance()->DisplayErrorText(msg);
612     break;
613   case QtCriticalMsg:
614     vtkOutputWindow::GetInstance()->DisplayErrorText(msg);
615     break;
616   case QtFatalMsg:
617     vtkOutputWindow::GetInstance()->DisplayErrorText(msg);
618     break;
619     }
620 }
621
622 /*!
623   \brief Activate module.
624   \param study current study
625   \return \c true if activaion is done successfully or 0 to prevent
626   activation on error
627 */
628 bool PVGUI_Module::activateModule( SUIT_Study* study )
629 {
630   myOldMsgHandler = qInstallMsgHandler(ParavisMessageOutput);
631   
632   SUIT_ExceptionHandler::addCleanUpRoutine( paravisCleanUp );
633
634   storeCommonWindowsState();
635
636   bool isDone = LightApp_Module::activateModule( study );
637   if ( !isDone ) return false;
638
639   showView( true );
640   if ( mySourcesMenuId != -1 ) menuMgr()->show(mySourcesMenuId);
641   if ( myFiltersMenuId != -1 ) menuMgr()->show(myFiltersMenuId);
642   if ( myMacrosMenuId != -1 ) menuMgr()->show(myMacrosMenuId);
643   if ( myToolbarsMenuId != -1 ) menuMgr()->show(myToolbarsMenuId);
644
645   // Update the various menus with the content pre-loaded in myGuiElements
646 //  QMenu* srcMenu = menuMgr()->findMenu( mySourcesMenuId );
647 //  myGuiElements->updateSourcesMenu(srcMenu);
648 //  QMenu* filtMenu = menuMgr()->findMenu( myFiltersMenuId );
649 //  myGuiElements->updateFiltersMenu(filtMenu);
650 //  QMenu* macMenu = menuMgr()->findMenu( myMacrosMenuId );
651 //  myGuiElements->updateMacrosMenu(macMenu);
652
653   setMenuShown( true );
654   setToolShown( true );
655
656   restoreDockWidgetsState();
657
658   QMenu* aMenu = menuMgr()->findMenu( myRecentMenuId );
659   if(aMenu) {
660     QList<QAction*> anActns = aMenu->actions();
661     for (int i = 0; i < anActns.size(); ++i) {
662       QAction* a = anActns.at(i);
663       if(a)
664         a->setVisible(true);
665     }
666   }
667
668   QList<QMenu*>::iterator it;
669   for (it = myMenus.begin(); it != myMenus.end(); ++it) {
670     QAction* a = (*it)->menuAction();
671     if(a)
672       a->setVisible(true);
673   }
674
675   if ( myRecentMenuId != -1 ) menuMgr()->show(myRecentMenuId);
676
677   ClientFindOrCreateParavisComponent(PARAVIS::GetCStudy(this));
678
679   return isDone;
680 }
681
682
683 /*!
684   \brief Deactivate module.
685   \param study current study
686   \return \c true if deactivaion is done successfully or 0 to prevent
687   deactivation on error
688 */
689 bool PVGUI_Module::deactivateModule( SUIT_Study* study )
690 {
691   MESSAGE("PARAVIS deactivation ...")
692
693   QMenu* aMenu = menuMgr()->findMenu( myRecentMenuId );
694   if(aMenu) {
695     QList<QAction*> anActns = aMenu->actions();
696     for (int i = 0; i < anActns.size(); ++i) {
697       QAction* a = anActns.at(i);
698       if(a)
699         a->setVisible(false);
700     }
701   }
702
703   QList<QMenu*>::iterator it;
704   for (it = myMenus.begin(); it != myMenus.end(); ++it) {
705     QAction* a = (*it)->menuAction();
706     if(a)
707       a->setVisible(false);
708   }
709
710   QList<QDockWidget*> aStreamingViews = application()->desktop()->findChildren<QDockWidget*>("pqStreamingControls");
711   foreach(QDockWidget* aView, aStreamingViews) {
712     if (!myDockWidgets.contains(aView))
713       myDockWidgets[aView] = aView->isVisible();
714   }
715
716   /*if (pqImplementation::helpWindow) {
717     pqImplementation::helpWindow->hide();
718     }*/
719   showView( false );
720   // hide menus
721   menuMgr()->hide(myRecentMenuId);
722   menuMgr()->hide(mySourcesMenuId);
723   menuMgr()->hide(myFiltersMenuId);
724   menuMgr()->hide(myMacrosMenuId);
725   menuMgr()->hide(myToolbarsMenuId);
726   setMenuShown( false );
727   setToolShown( false );
728
729   saveDockWidgetsState();
730
731   SUIT_ExceptionHandler::removeCleanUpRoutine( paravisCleanUp );
732
733   if (myOldMsgHandler)
734     qInstallMsgHandler(myOldMsgHandler);
735
736   restoreCommonWindowsState();
737   
738   return LightApp_Module::deactivateModule( study );
739 }
740
741
742 /*!
743   \brief Called when application is closed.
744
745   Process finalize application functionality from ParaView in order to save server settings
746   and nullify application pointer if the application is being closed.
747
748   \param theApp application
749 */
750 void PVGUI_Module::onApplicationClosed( SUIT_Application* theApp )
751 {
752   PVViewer_ViewManager::ParaviewCleanup();
753
754   int aAppsNb = SUIT_Session::session()->applications().size();
755   if (aAppsNb == 1) {
756     deleteTemporaryFiles();
757   }
758   CAM_Module::onApplicationClosed(theApp);
759 }
760
761
762 /*!
763   \brief Deletes temporary files created during import operation from VISU
764 */
765 void PVGUI_Module::deleteTemporaryFiles()
766 {
767   foreach(QString aFile, myTemporaryFiles) {
768     if (QFile::exists(aFile)) {
769       QFile::remove(aFile);
770     }
771   }
772 }
773
774
775 /*!
776   \brief Called when study is closed.
777
778   Removes data model from the \a study.
779
780   \param study study being closed
781 */
782 void PVGUI_Module::studyClosed(SUIT_Study* study)
783 {
784   clearParaviewState();
785
786   LightApp_Module::studyClosed(study);
787 }
788
789 /*!
790   \brief Called when study is opened.
791 */
792 void PVGUI_Module::onModelOpened()
793 {
794   _PTR(Study) studyDS = PARAVIS::GetCStudy(this);
795   if(!studyDS) {
796     return;
797   }
798
799   _PTR(SComponent) paravisComp =
800     studyDS->FindComponent(PARAVIS_MODULE_NAME);
801   if(!paravisComp) {
802     return;
803   }
804
805   _PTR(ChildIterator) anIter(studyDS->NewChildIterator(paravisComp));
806   for (; anIter->More(); anIter->Next()) {
807     _PTR(SObject) aSObj = anIter->Value();
808     _PTR(GenericAttribute) anAttr;
809     if (!aSObj->FindAttribute(anAttr, "AttributeLocalID")) {
810       continue;
811     }
812     _PTR(AttributeLocalID) anID(anAttr);
813     if (anID->Value() == PVSTATEID) {
814       myStateCounter++;
815     }
816   }
817 }
818
819 /*!
820 \brief Returns IOR of current engine
821 */
822 QString PVGUI_Module::engineIOR() const
823 {
824   CORBA::String_var anIOR = GetCPPEngine()->GetIOR();
825   return QString(anIOR.in());
826 }
827
828 /*!
829   \brief Open file of format supported by ParaView
830 */
831 void PVGUI_Module::openFile(const char* theName)
832 {
833   QStringList aFiles;
834   aFiles<<theName;
835   pqLoadDataReaction::loadData(aFiles);
836 }
837
838 /**!
839  * Start trace invoking the newly introduced C++ API (PV 4.2)
840  * (inspired from pqTraceReaction::start())
841  */
842 void PVGUI_Module::startTrace()
843 {
844   vtkSMSessionProxyManager* pxm = pqActiveObjects::instance().activeServer()->proxyManager();
845
846   vtkSmartPointer<vtkSMProxy> proxy;
847   proxy.TakeReference(pxm->NewProxy("pythontracing", "PythonTraceOptions"));
848   if (proxy)
849     {
850       vtkNew<vtkSMParaViewPipelineController> controller;
851       controller->InitializeProxy(proxy);
852     }
853   vtkSMTrace* trace = vtkSMTrace::StartTrace();
854   if (proxy)
855     {
856       // Set manually the properties entered via the dialog box poping-up when requiring
857       // a trace start in PV4.2 (trace options)
858       trace->SetPropertiesToTraceOnCreate(vtkSMTrace::RECORD_USER_MODIFIED_PROPERTIES);
859       trace->SetFullyTraceSupplementalProxies(false);
860     }
861 }
862
863 void PVGUI_Module::stopTrace()
864 {
865   vtkSMTrace::StopTrace();
866 }
867
868 void PVGUI_Module::executeScript(const char *script)
869 {
870 #ifndef WNT
871   pqPythonManager* manager = qobject_cast<pqPythonManager*>(
872                              pqApplicationCore::instance()->manager("PYTHON_MANAGER"));
873   if (manager)  {
874     pqPythonDialog* pyDiag = manager->pythonShellDialog();
875     if (pyDiag) {
876       pyDiag->runString(script);  
877       }
878     }
879 #endif
880 }
881
882 ///**
883 // *  Debug function printing out the given interpreter's execution context
884 // */
885 //void printInterpContext(PyInterp_Interp * interp )
886 //{
887 //  // Extract __smtraceString from interpreter's context
888 //  const PyObject* ctxt = interp->getExecutionContext();
889 //
890 //  PyObject* lst = PyDict_Keys((PyObject *)ctxt);
891 //  Py_ssize_t siz = PyList_GET_SIZE(lst);
892 //  for (Py_ssize_t i = 0; i < siz; i++)
893 //    {
894 //      PyObject * elem = PyList_GetItem(lst, i);
895 //      if (PyString_Check(elem))
896 //        {
897 //          std::cout << "At pos:" << i << ", " << PyString_AsString(elem) << std::endl;
898 //        }
899 //      else
900 //        std::cout << "At pos:" << i << ", not a string!" << std::endl;
901 //    }
902 //  Py_XDECREF(lst);
903 //}
904
905 /*!
906   \brief Returns trace string
907 */
908 static const QString MYReplaceStr("paraview.simple");
909 QString PVGUI_Module::getTraceString()
910 {
911   vtkSMTrace *tracer = vtkSMTrace::GetActiveTracer();
912   if (!tracer) // trace is not started
913     return QString("");
914
915   QString traceString(tracer->GetCurrentTrace());
916   std::stringstream nl; nl << std::endl; // surely there is some Qt trick to do that in a portable way??
917   QString end_line(nl.str().c_str());
918   // 'import pvsimple' is necessary to fix the first call to DisableFirstRenderCamera in the paraview trace
919   // 'ShowParaviewView()' ensure there is an opened viewing window (otherwise SEGFAULT!)
920   traceString = "import pvsimple" + end_line +
921                 "pvsimple.ShowParaviewView()" + end_line + traceString;
922
923   // Replace import "paraview.simple" by "pvsimple"
924   if ((!traceString.isNull()) && traceString.length() != 0) {
925     int aPos = traceString.indexOf(MYReplaceStr);
926     while (aPos != -1) {
927       traceString = traceString.replace(aPos, MYReplaceStr.length(), "pvsimple");
928       aPos = traceString.indexOf(MYReplaceStr, aPos);
929     }
930   }
931
932   return traceString;
933 }
934
935 /*!
936   \brief Saves trace string to disk file
937 */
938 void PVGUI_Module::saveTrace(const char* theName)
939 {
940   QFile file(theName);
941   if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
942     MESSAGE( "Could not open file:" << theName );
943     return;
944   }
945   QTextStream out(&file);
946   out << getTraceString();
947   file.close();
948 }
949
950 /*!
951   \brief Saves ParaView state to a disk file
952 */
953 void PVGUI_Module::saveParaviewState(const char* theFileName)
954 {
955   pqApplicationCore::instance()->saveState(theFileName);
956 }
957
958 /*!
959   \brief Delete all objects for Paraview Pipeline Browser
960 */
961 void PVGUI_Module::clearParaviewState()
962 {
963   QAction* deleteAllAction = action(DeleteAllId);
964   if (deleteAllAction) {
965     deleteAllAction->activate(QAction::Trigger);
966   }
967 }
968
969 /*!
970   \brief Restores ParaView state from a disk file
971
972   If toClear == true, the current ojects will be deleted
973 */
974 void PVGUI_Module::loadParaviewState(const char* theFileName)
975 {
976   pqApplicationCore::instance()->loadState(theFileName, getActiveServer());
977 }
978
979 /*!
980   \brief Returns current active ParaView server
981 */
982 pqServer* PVGUI_Module::getActiveServer()
983 {
984   return pqApplicationCore::instance()->getActiveServer();
985 }
986
987
988 /*!
989   \brief Creates PARAVIS preference pane 
990 */
991 void PVGUI_Module::createPreferences()
992 {
993   // Paraview settings tab
994   int aParaViewSettingsTab = addPreference( tr( "TIT_PVIEWSETTINGS" ) );
995
996   setPreferenceProperty(aParaViewSettingsTab, "stretch", false );
997   int aPanel = addPreference(QString(), aParaViewSettingsTab, LightApp_Preferences::UserDefined, PARAVIS_MODULE_NAME, "");
998
999   setPreferenceProperty(aPanel, "content", (qint64)(new PVGUI_ParaViewSettingsPane()));
1000
1001   // Paravis settings tab
1002   int aParaVisSettingsTab = addPreference( tr( "TIT_PVISSETTINGS" ) );
1003   addPreference( tr( "PREF_STOP_TRACE" ), aParaVisSettingsTab, LightApp_Preferences::Bool, PARAVIS_MODULE_NAME, "stop_trace");
1004
1005   addPreference( tr( "PREF_NO_EXT_PVSERVER" ), aParaVisSettingsTab, LightApp_Preferences::Bool, PARAVIS_MODULE_NAME, "no_ext_pv_server");
1006
1007   int aSaveType = addPreference(tr( "PREF_SAVE_TYPE_LBL" ), aParaVisSettingsTab,
1008                                 LightApp_Preferences::Selector,
1009                                 PARAVIS_MODULE_NAME, "savestate_type");
1010   QList<QVariant> aIndices;
1011   QStringList aStrings;
1012   aIndices<<0<<1<<2;
1013   aStrings<<tr("PREF_SAVE_TYPE_0");
1014   aStrings<<tr("PREF_SAVE_TYPE_1");
1015   aStrings<<tr("PREF_SAVE_TYPE_2");
1016   setPreferenceProperty(aSaveType, "strings", aStrings);
1017   setPreferenceProperty(aSaveType, "indexes", aIndices);
1018 }
1019
1020 /*!
1021   \brief Creates ParaViS context menu popup
1022 */
1023 void PVGUI_Module::contextMenuPopup(const QString& theClient, QMenu* theMenu, QString& theTitle)
1024 {
1025   LightApp_Module::contextMenuPopup(theClient, theMenu, theTitle);
1026
1027   // Check if we are in Object Browser
1028   SUIT_DataBrowser* ob = getApp()->objectBrowser();
1029   bool isOBClient = (ob && theClient == ob->popupClientType());
1030   if (!isOBClient) {
1031     return;
1032   }
1033
1034   // Get list of selected objects
1035   LightApp_SelectionMgr* aSelectionMgr = getApp()->selectionMgr();
1036   SALOME_ListIO aListIO;
1037   aSelectionMgr->selectedObjects(aListIO);
1038   if (aListIO.Extent() == 1 && aListIO.First()->hasEntry()) {
1039     QString entry = QString(aListIO.First()->getEntry());
1040
1041     // Get active study
1042     SalomeApp_Study* activeStudy =
1043       dynamic_cast<SalomeApp_Study*>(getApp()->activeStudy());
1044     if(!activeStudy) {
1045       return;
1046     }
1047
1048     // Get SALOMEDS client study
1049     _PTR(Study) studyDS = activeStudy->studyDS();
1050     if(!studyDS) {
1051       return;
1052     }
1053
1054     QString paravisDataType(PARAVIS_MODULE_NAME);
1055     if(activeStudy && activeStudy->isComponent(entry) &&
1056        activeStudy->componentDataType(entry) == paravisDataType) {
1057       // ParaViS module object
1058       theMenu->addSeparator();
1059       theMenu->addAction(action(SaveStatePopupId));
1060     }
1061     else {
1062       // Try to get state object
1063       _PTR(SObject) stateSObj =
1064           studyDS->FindObjectID(entry.toLatin1().constData());
1065       if (!stateSObj) {
1066           return;
1067       }
1068
1069       // Check local id
1070       _PTR(GenericAttribute) anAttr;
1071       if (!stateSObj->FindAttribute(anAttr, "AttributeLocalID")) {
1072           return;
1073       }
1074
1075       _PTR(AttributeLocalID) anID(anAttr);
1076
1077       if (anID->Value() == PVSTATEID) {
1078         // Paraview state object
1079         theMenu->addSeparator();
1080         theMenu->addAction(action(AddStatePopupId));
1081         theMenu->addAction(action(CleanAndAddStatePopupId));
1082         theMenu->addSeparator();
1083         theMenu->addAction(action(ParaVisRenameId));
1084         theMenu->addAction(action(ParaVisDeleteId));
1085       }
1086     }
1087   }
1088 }
1089
1090 /*!
1091   \brief. Show ParaView python trace.
1092 */
1093 void PVGUI_Module::onShowTrace()
1094 {
1095   if (!myTraceWindow) {
1096     myTraceWindow = new pqPythonScriptEditor(getApp()->desktop());
1097   }
1098   myTraceWindow->setText(getTraceString());
1099   myTraceWindow->show();
1100   myTraceWindow->raise();
1101   myTraceWindow->activateWindow();
1102 }
1103
1104
1105 /*!
1106   \brief. Re-initialize ParaView python trace.
1107 */
1108 void PVGUI_Module::onRestartTrace()
1109 {
1110   stopTrace();
1111   startTrace();
1112 }
1113
1114 /*!
1115   \brief Save state under the module root object.
1116 */
1117 void PVGUI_Module::onSaveMultiState()
1118 {
1119   // Create state study object
1120   
1121   // Get SALOMEDS client study
1122   _PTR(Study) studyDS = PARAVIS::GetCStudy(this);
1123   if(!studyDS) {
1124     return;
1125   }
1126
1127   _PTR(SComponent) paravisComp = 
1128       studyDS->FindComponent(PARAVIS_MODULE_NAME);
1129   if(!paravisComp) {
1130     return;
1131   }
1132
1133   // Unlock the study if it is locked
1134   bool isLocked = studyDS->GetProperties()->IsLocked();
1135   if (isLocked) {
1136     studyDS->GetProperties()->SetLocked(false);
1137   }
1138   
1139   QString stateName = tr("SAVED_PARAVIEW_STATE_NAME") + 
1140     QString::number(myStateCounter + 1);
1141
1142   _PTR(StudyBuilder) studyBuilder = studyDS->NewBuilder();
1143   _PTR(SObject) newSObj = studyBuilder->NewObject(paravisComp);
1144
1145   // Set name
1146   _PTR(GenericAttribute) anAttr;
1147   anAttr = studyBuilder->FindOrCreateAttribute(newSObj, "AttributeName");
1148   _PTR(AttributeName) nameAttr(anAttr);
1149   
1150   nameAttr->SetValue(stateName.toLatin1().constData());
1151
1152   // Set local id
1153   anAttr = studyBuilder->FindOrCreateAttribute(newSObj, "AttributeLocalID");
1154   _PTR(AttributeLocalID) localIdAttr(anAttr);
1155   
1156   localIdAttr->SetValue(PVSTATEID);
1157
1158   // Set file name
1159   QString stateEntry = QString::fromStdString(newSObj->GetID());
1160  
1161   // File name for state saving
1162   QString tmpDir = QString::fromStdString(SALOMEDS_Tool::GetTmpDir());
1163   QString fileName = QString("%1_paravisstate:%2").arg(tmpDir, stateEntry);
1164
1165   anAttr = studyBuilder->FindOrCreateAttribute(newSObj, "AttributeString");
1166   _PTR(AttributeString) stringAttr(anAttr);
1167   
1168   stringAttr->SetValue(fileName.toLatin1().constData());
1169
1170   // Lock the study back if necessary
1171   if (isLocked) {
1172     studyDS->GetProperties()->SetLocked(true);
1173   }
1174   
1175   // Save state
1176   saveParaviewState(fileName.toLatin1().constData());
1177   myTemporaryFiles.append(fileName);
1178   
1179   // Increment the counter
1180   myStateCounter++;
1181
1182   updateObjBrowser();
1183 }
1184
1185 /*!
1186   \brief Restore the selected state by merging with the current one.
1187 */
1188 void PVGUI_Module::onAddState()
1189 {
1190   loadSelectedState(false);
1191 }
1192
1193 /*!
1194   \brief Clean the current state and restore the selected one.
1195 */
1196 void PVGUI_Module::onCleanAddState()
1197 {
1198   loadSelectedState(true);
1199 }
1200
1201 /*!
1202   \brief Rename the selected object.
1203 */
1204 void PVGUI_Module::onRename()
1205 {
1206   LightApp_SelectionMgr* aSelectionMgr = getApp()->selectionMgr();
1207   SALOME_ListIO aListIO;
1208   aSelectionMgr->selectedObjects(aListIO);
1209   
1210   if (aListIO.Extent() == 1 && aListIO.First()->hasEntry()) {
1211     std::string entry = aListIO.First()->getEntry();
1212     
1213     // Get SALOMEDS client study 
1214     _PTR(Study) studyDS = PARAVIS::GetCStudy(this);
1215     if(!studyDS) {
1216       return;
1217     }
1218     
1219     // Unlock the study if it is locked
1220     bool isLocked = studyDS->GetProperties()->IsLocked();
1221     if (isLocked) {
1222       studyDS->GetProperties()->SetLocked(false);
1223     }
1224     
1225     // Rename the selected state object
1226     _PTR(SObject) stateSObj = studyDS->FindObjectID(entry);
1227     if (!stateSObj) {
1228       return;
1229     }
1230     
1231     _PTR(GenericAttribute) anAttr;
1232     if (stateSObj->FindAttribute(anAttr, "AttributeName")) {
1233       _PTR(AttributeName) nameAttr (anAttr);
1234       QString newName = 
1235           LightApp_NameDlg::getName(getApp()->desktop(), nameAttr->Value().c_str());
1236       if (!newName.isEmpty()) {
1237         nameAttr->SetValue(newName.toLatin1().constData());
1238         aListIO.First()->setName(newName.toLatin1().constData());
1239       }
1240     }
1241     
1242     // Lock the study back if necessary
1243     if (isLocked) {
1244       studyDS->GetProperties()->SetLocked(true);
1245     }
1246     
1247     // Update object browser
1248     updateObjBrowser();
1249     
1250   }
1251 }
1252
1253 /*!
1254   \brief Delete the selected objects.
1255 */
1256 void PVGUI_Module::onDelete()
1257 {
1258   LightApp_SelectionMgr* aSelectionMgr = getApp()->selectionMgr();
1259   SALOME_ListIO aListIO;
1260   aSelectionMgr->selectedObjects(aListIO);
1261   
1262   if (aListIO.Extent() == 1 && aListIO.First()->hasEntry()) {
1263     std::string entry = aListIO.First()->getEntry();
1264     
1265     // Get SALOMEDS client study 
1266     _PTR(Study) studyDS = PARAVIS::GetCStudy(this);
1267     if(!studyDS) {
1268       return;
1269     }
1270     
1271     // Unlock the study if it is locked
1272     bool isLocked = studyDS->GetProperties()->IsLocked();
1273     if (isLocked) {
1274       studyDS->GetProperties()->SetLocked(false);
1275     }
1276     
1277     // Remove the selected state from the study
1278     _PTR(StudyBuilder) studyBuilder = studyDS->NewBuilder();
1279     _PTR(SObject) stateSObj = studyDS->FindObjectID(entry);
1280     studyBuilder->RemoveObject(stateSObj);
1281     
1282     // Lock the study back if necessary
1283     if (isLocked) {
1284       studyDS->GetProperties()->SetLocked(true);
1285     }
1286     
1287     // Update object browser
1288     updateObjBrowser();
1289   }
1290 }
1291
1292 void PVGUI_Module::onPushTraceTimer()
1293 {
1294   //MESSAGE("onPushTraceTimer(): Pushing trace to engine...");
1295   GetEngine()->PutPythonTraceStringToEngine(getTraceString().toStdString().c_str());
1296 }
1297
1298 /*!
1299   \brief Discover help project files from the resources.
1300   \return name of the help file. 
1301 */
1302 QString PVGUI_Module::getHelpFileName() {
1303   QString aPVHome(getenv("PVHOME"));
1304   if (aPVHome.isNull()) {
1305     qWarning("Wariable PVHOME is not defined");
1306     return QString();
1307   }
1308   QChar aSep = QDir::separator();
1309   //PARAVIEW_VERSION from the vtkPVConfig.h file
1310   QString aFileName =  aPVHome + aSep + "share" + aSep + "doc" + aSep + "paraview-"+ PARAVIEW_VERSION + aSep + "paraview.qch";
1311   return aFileName;
1312 }
1313
1314
1315 /*!
1316   \brief Load selected paraview state
1317
1318   If toClear == true, the current state will be cleared
1319 */
1320 void PVGUI_Module::loadSelectedState(bool toClear)
1321 {
1322   QString fileName;
1323
1324   LightApp_SelectionMgr* aSelectionMgr = getApp()->selectionMgr();
1325   SALOME_ListIO aListIO;
1326   aSelectionMgr->selectedObjects(aListIO);
1327   
1328   if (aListIO.Extent() == 1 && aListIO.First()->hasEntry()) {
1329     std::string entry = aListIO.First()->getEntry();
1330     
1331     // Get SALOMEDS client study 
1332     _PTR(Study) studyDS = PARAVIS::GetCStudy(this);
1333     if(!studyDS) {
1334       return;
1335     }
1336
1337     // Check local id
1338     _PTR(SObject) stateSObj = studyDS->FindObjectID(entry);
1339     _PTR(GenericAttribute) anAttr;
1340     if (!stateSObj->FindAttribute(anAttr, "AttributeLocalID")) {
1341       return;
1342     }
1343     _PTR(AttributeLocalID) anID(anAttr);
1344     if (!anID->Value() == PVSTATEID) {
1345       return;
1346     }
1347
1348     // Get state file name
1349     if (stateSObj->FindAttribute(anAttr, "AttributeString")) {
1350       _PTR(AttributeString) aStringAttr(anAttr);
1351       QString stringValue(aStringAttr->Value().c_str());
1352
1353       if (QFile::exists(stringValue)) {
1354           fileName = stringValue;
1355       }
1356     }
1357   }
1358   
1359   if (!fileName.isEmpty()) {
1360     if (toClear) {
1361       clearParaviewState();
1362     }
1363
1364     loadParaviewState(fileName.toLatin1().constData());
1365   } 
1366   else {
1367     SUIT_MessageBox::critical(getApp()->desktop(),
1368                               tr("ERR_ERROR"),
1369                               tr("ERR_STATE_CANNOT_BE_RESTORED"));
1370   }
1371 }
1372
1373 /*!
1374   \fn CAM_Module* createModule();
1375   \brief Export module instance (factory function).
1376   \return new created instance of the module
1377 */
1378
1379 #ifdef WNT
1380 #define PVGUI_EXPORT __declspec(dllexport)
1381 #else   // WNT
1382 #define PVGUI_EXPORT
1383 #endif  // WNT
1384
1385 extern "C" {
1386
1387   bool flag = false;
1388   PVGUI_EXPORT CAM_Module* createModule() {
1389     return new PVGUI_Module();
1390   }
1391   
1392   PVGUI_EXPORT char* getModuleVersion() {
1393     return (char*)PARAVIS_VERSION_STR;
1394   }
1395 }