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