Salome HOME
Merge from V6_main_20120808 08Aug12
[modules/paravis.git] / src / PVGUI / PVGUI_Module.cxx
1 // PARAVIS : ParaView wrapper SALOME module
2 //
3 // Copyright (C) 2010-2012  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.
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 // Author : Julia DOROVSKIKH
23
24 #include <Standard_math.hxx>  // E.A. must be included before Python.h to fix compilation on windows
25 #ifdef HAVE_FINITE
26 #undef HAVE_FINITE            // VSR: avoid compilation warning on Linux : "HAVE_FINITE" redefined
27 #endif
28 #include <vtkPython.h> // Python first
29 #include "PVGUI_Module.h"
30
31 #include "SALOMEconfig.h"
32 #ifdef WITH_VISU
33 #include CORBA_CLIENT_HEADER(VISU_Gen)
34 #endif
35 #include CORBA_SERVER_HEADER(SALOMEDS)
36
37
38 #include "PARAVIS_Gen_i.hh"
39
40 #include "PV_Tools.h"
41
42 #include "PVGUI_ViewModel.h"
43 #include "PVGUI_ViewManager.h"
44 #include "PVGUI_ViewWindow.h"
45 #include "PVGUI_Tools.h"
46 #include "PVGUI_ParaViewSettingsPane.h"
47 #include "PVGUI_OutputWindowAdapter.h"
48
49 #include <SUIT_DataBrowser.h>
50 #include <SUIT_Desktop.h>
51 #include <SUIT_MessageBox.h>
52 #include <SUIT_ResourceMgr.h>
53 #include <SUIT_Session.h>
54 #include <SUIT_OverrideCursor.h>
55
56 // SALOME Includes
57 #include "SALOME_LifeCycleCORBA.hxx"
58 #include "SALOMEDS_SObject.hxx"
59
60 #include "LightApp_SelectionMgr.h"
61 #include "LightApp_NameDlg.h"
62
63 #include <SalomeApp_Application.h>
64 #include <SalomeApp_Study.h>
65 #include <SALOME_ListIO.hxx>
66 #include <SALOMEDS_Tool.hxx>
67 #include <PyInterp_Dispatcher.h>
68
69 #include <QtxActionMenuMgr.h>
70 #include <QtxActionToolMgr.h>
71
72 #include <QAction>
73 #include <QApplication>
74 #include <QCursor>
75 #include <QDir>
76 #include <QFile>
77 #include <QFileInfo>
78 #include <QIcon>
79 #include <QInputDialog>
80 #include <QMenu>
81 #include <QStatusBar>
82 #include <QString>
83 #include <QStringList>
84 #include <QTimer>
85 #include <QToolBar>
86 #include <QTextStream>
87 #include <QShortcut>
88 #include <QDockWidget>
89 #include <QHelpEngine>
90
91 #include <pqApplicationCore.h>
92 #include <pqPVApplicationCore.h>
93 #include <pqActiveView.h>
94 #include <pqObjectBuilder.h>
95 #include <pqOptions.h>
96 #include <pqRenderView.h>
97 #include <pqServer.h>
98 #include <pqUndoStack.h>
99 #include <pqVCRController.h>
100 #include <pqTabbedMultiViewWidget.h>
101 #include <pqPipelineSource.h>
102 //#include <vtkPVMain.h>
103 #include <vtkProcessModule.h>
104 #include <pqParaViewBehaviors.h>
105 #include <pqHelpReaction.h>
106 #include <vtkOutputWindow.h>
107 #include <pqPluginManager.h>
108 //#include <vtkPVPluginInformation.h>
109 #include "pqInterfaceTracker.h"
110 #include <pqSettings.h>
111 #include <pqPythonDialog.h>
112 #include <pqPythonManager.h>
113 #include <pqPythonShell.h>
114 #include <pqBrandPluginsLoader.h>
115 #include <pqLoadDataReaction.h>
116 #include <vtkEventQtSlotConnect.h>
117 #include <pqPythonScriptEditor.h>
118 #include <pqStandardSummaryPanelImplementation.h>
119 #include <pqCollaborationBehavior.h>
120
121 #include <PARAVIS_version.h>
122
123 #include <vtkPVConfig.h>
124
125 /*
126  * Make sure all the kits register their classes with vtkInstantiator.
127  * Since ParaView uses Tcl wrapping, all of VTK is already compiled in
128  * anyway.  The instantiators will add no more code for the linker to
129  * collect.
130  */
131
132 #include <vtkCommonInstantiator.h>
133 #include <vtkFilteringInstantiator.h>
134 #include <vtkGenericFilteringInstantiator.h>
135 #include <vtkIOInstantiator.h>
136 #include <vtkImagingInstantiator.h>
137 #include <vtkInfovisInstantiator.h>
138 #include <vtkGraphicsInstantiator.h>
139
140 #include <vtkRenderingInstantiator.h>
141 #include <vtkVolumeRenderingInstantiator.h>
142 #include <vtkHybridInstantiator.h>
143 #include <vtkParallelInstantiator.h>
144
145 #include <pqAlwaysConnectedBehavior.h>
146 #include <pqApplicationCore.h>
147 #include <pqAutoLoadPluginXMLBehavior.h>
148 #include <pqCommandLineOptionsBehavior.h>
149 #include <pqCrashRecoveryBehavior.h>
150 #include <pqDataTimeStepBehavior.h>
151 #include <pqDefaultViewBehavior.h>
152 #include <pqDeleteBehavior.h>
153 #include <pqObjectPickingBehavior.h>
154 #include <pqPersistentMainWindowStateBehavior.h>
155 #include <pqPipelineContextMenuBehavior.h>
156 #include <pqPluginActionGroupBehavior.h>
157 #include <pqPluginDockWidgetsBehavior.h>
158 #include <pqPluginManager.h>
159 #include <pqPVNewSourceBehavior.h>
160 #include <pqSpreadSheetVisibilityBehavior.h>
161 #include <pqStandardViewModules.h>
162 #include <pqUndoRedoBehavior.h>
163 #include <pqViewFrameActionsBehavior.h>
164 #include <pqServerManagerObserver.h>
165
166
167 //----------------------------------------------------------------------------
168 pqPVApplicationCore* PVGUI_Module::MyCoreApp = 0;
169 //PVGUI_OutputWindowAdapter* PVGUI_Module::pqImplementation::OutputWindowAdapter = 0;
170 //QPointer<pqHelpWindow> PVGUI_Module::pqImplementation::helpWindow = 0;
171
172 PVGUI_Module* ParavisModule = 0;
173
174 /*!
175   \mainpage
176
177   <h2>Building and installing PARAVIS</h2>
178   As any other SALOME module, PARAVIS requires PARAVIS_ROOT_DIR environment variable to be set to PARAVIS
179   installation directory.
180   Other variables needed for correct detection of ParaView location:
181   \li PVHOME - points at the ParaView installation directory tree
182   \li PVVERSION - number of ParaView version
183
184   It also requires common SALOME environment including GUI_ROOT_DIR and other prerequsites.
185
186
187   PARAVIS module can be launched using the following commands:
188   \li Full SALOME configuration
189   \code
190   runSalome --modules="PARAVIS"
191   \endcode
192
193   <h2>ParaView GUI integration</h2>
194   <h3>ParaView GUI integration overview</h3>
195
196   The main idea is to reuse ParaView GUI internal logic as much as possible, providing a layer 
197   between it and SALOME GUI that hides the following SALOME GUI implementation details from ParaView:
198
199   \li SALOME GUI executable and Qt event loop
200   \li SALOME GUI desktop
201   \li Dock windows areas
202   \li SALOME menu and toolbar managers
203
204   Major part of the integration is implemented in PVGUI_Module class.
205
206   <h3>ParaView client initalization</h3>
207
208   ParaView client initalization is performed when an instance of PVGUI_Module class has been created 
209   and \link PVGUI_Module::initialize() PVGUI_Module::initialize()\endlink method is called by SALOME GUI.
210   The actual client start-up is done in \link PVGUI_Module::pvInit() PVGUI_Module::pvInit()\endlink method. 
211   
212
213   <h3>Multi-view manager</h3>
214
215   SALOME GUI requires that each kind of view be implemnted with help of (at least) three classes. For ParaView multi-view manager 
216   these are:
217
218   \li PVGUI_ViewManager - view manager class
219   \li PVGUI_Viewer      - view model class
220   \li PVGUI_ViewWindow  - view window class that acts as a parent for %pqViewManager
221
222   Single instances of PVGUI_ViewManager and PVGUI_ViewWindow classes are created by \link PVGUI_Module::showView() 
223   PVGUI_Module::showView()\endlink method upon the first PARAVIS module activation. The same method hides the multi-view manager 
224   when the module is deactivated (the user switches to another module or a study is closed). 
225   A special trick is used to make PVGUI_ViewWindow the parent of %pqViewManager widget. It is created initally by %pqMainWindowCore
226   with the desktop as a parent, so when it is shown PVGUI_ViewWindow instance is passed to its setParent() method. In  
227   \link PVGUI_ViewWindow::~PVGUI_ViewWindow() PVGUI_ViewWindow::~PVGUI_ViewWindow()\endlink the parent is nullified to avoid deletion
228   of %pqViewManager widget that would break %pqMainWindowCore class.
229
230   <h3>ParaView plugins</h3>
231   ParaView server and client plugins are managed by %pqMainWindowCore slots that has full access to PARAVIS menus and toolbars. 
232   As a result they appears automatically in PARAVIS menus and toolbars if loaded successfully.
233 */
234
235 /*!
236   \class PVGUI_Module
237   \brief Implementation 
238          SALOME module wrapping ParaView GUI.
239 */
240
241 /*!
242   \brief Constructor. Sets the default name for the module.
243 */
244 PVGUI_Module::PVGUI_Module()
245   : SalomeApp_Module( "PARAVIS" ),
246     LightApp_Module( "PARAVIS" ),
247     //    Implementation( 0 ),
248     mySelectionControlsTb( -1 ),
249     mySourcesMenuId( -1 ),
250     myFiltersMenuId( -1 ),
251     myMacrosMenuId(-1),
252     myToolbarsMenuId(-1),
253     myRecentMenuId(-1),
254     myOldMsgHandler(0),
255     myTraceWindow(0),
256     myStateCounter(0)
257 {
258 #ifdef HAS_PV_DOC
259   Q_INIT_RESOURCE( PVGUI );
260 #endif
261   ParavisModule = this;
262
263   // Clear old macros
264   QString aDestPath = QString( "%1/.config/%2/Macros" ).arg( QDir::homePath() ).arg( QApplication::applicationName() );
265   QStringList aFilter;
266   aFilter << "*.py";
267
268   QDir aDestDir(aDestPath);
269   QStringList aDestFiles = aDestDir.entryList(aFilter, QDir::Files);
270   foreach (QString aStr, aDestFiles) {
271     aDestDir.remove(aStr);
272   }
273 }
274
275 /*!
276   \brief Destructor.
277 */
278 PVGUI_Module::~PVGUI_Module()
279 {
280 }
281
282
283
284 /*!
285   \brief Initialize module. Creates menus, prepares context menu, etc.
286   \param app SALOME GUI application instance
287 */
288 void PVGUI_Module::initialize( CAM_Application* app )
289 {
290   SalomeApp_Module::initialize( app );
291
292   // Create ParaViS actions
293   createActions();
294   // Create ParaViS menus
295   createMenus();
296
297   // Uncomment to debug ParaView initialization
298   // "aa" used instead of "i" as GDB doesn't like "i" variables :)
299   /*
300   int aa = 1;
301   while( aa ){
302     aa = aa;
303   }
304   */
305   
306   // Initialize ParaView client
307   pvInit();
308
309   // Create GUI elements (menus, toolbars, dock widgets)
310   //if ( !Implementation ){
311     SalomeApp_Application* anApp = getApp();
312     SUIT_Desktop* aDesktop = anApp->desktop();
313
314     // connect(aDesktop, SIGNAL()
315
316     // Remember current state of desktop toolbars
317     QList<QToolBar*> foreignToolbars = aDesktop->findChildren<QToolBar*>();
318
319     // Simulate ParaView client main window
320     //Implementation = new pqImplementation( aDesktop );
321
322     setupDockWidgets();
323     
324     pvCreateActions();
325     pvCreateToolBars();
326     pvCreateMenus();
327
328     // new pqParaViewBehaviors(anApp->desktop(), this);
329     // Has to be replaced in order to exclude using of pqQtMessageHandlerBehaviour
330     //  Start pqParaViewBehaviors
331     // Register ParaView interfaces.
332     //pqPluginManager* pgm = pqApplicationCore::instance()->getPluginManager();
333     pqInterfaceTracker* pgm = pqApplicationCore::instance()->interfaceTracker();
334
335     // * adds support for standard paraview views.
336     pgm->addInterface(new pqStandardViewModules(pgm));
337     pgm->addInterface(new pqStandardSummaryPanelImplementation(pgm));
338
339     // Load plugins distributed with application.
340     pqApplicationCore::instance()->loadDistributedPlugins();
341
342     // Define application behaviors.
343     //new pqQtMessageHandlerBehavior(this);
344     new pqDataTimeStepBehavior(this);
345     new pqViewFrameActionsBehavior(this);
346     new pqSpreadSheetVisibilityBehavior(this);
347     new pqPipelineContextMenuBehavior(this);
348     new pqDefaultViewBehavior(this);
349     new pqAlwaysConnectedBehavior(this);
350     new pqPVNewSourceBehavior(this);
351     new pqDeleteBehavior(this);
352     new pqUndoRedoBehavior(this);
353     new pqCrashRecoveryBehavior(this);
354     new pqAutoLoadPluginXMLBehavior(this);
355     new pqPluginDockWidgetsBehavior(aDesktop);
356     //new pqVerifyRequiredPluginBehavior(this);
357     new pqPluginActionGroupBehavior(aDesktop);
358     //new pqFixPathsInStateFilesBehavior(this);
359     new pqCommandLineOptionsBehavior(this);
360     new pqPersistentMainWindowStateBehavior(aDesktop);
361     new pqObjectPickingBehavior(aDesktop);
362     new pqCollaborationBehavior(this);
363
364     // Setup quick-launch shortcuts.
365     QShortcut *ctrlSpace = new QShortcut(Qt::CTRL + Qt::Key_Space, aDesktop);
366     QObject::connect(ctrlSpace, SIGNAL(activated()),
367       pqApplicationCore::instance(), SLOT(quickLaunch()));
368     QShortcut *altSpace = new QShortcut(Qt::ALT + Qt::Key_Space, aDesktop);
369     QObject::connect(altSpace, SIGNAL(activated()),
370       pqApplicationCore::instance(), SLOT(quickLaunch()));
371     //  End pqParaViewBehaviors
372
373
374     SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
375     QString aPath = resMgr->stringValue("resources", "PARAVIS", QString());
376     if (!aPath.isNull()) {
377       MyCoreApp->loadConfiguration(aPath + QDir::separator() + "ParaViewFilters.xml");
378       MyCoreApp->loadConfiguration(aPath + QDir::separator() + "ParaViewReaders.xml");
379       MyCoreApp->loadConfiguration(aPath + QDir::separator() + "ParaViewSources.xml");
380       MyCoreApp->loadConfiguration(aPath + QDir::separator() + "ParaViewWriters.xml");
381     }
382      
383     // Force creation of engine
384     PARAVIS::GetParavisGen(this);
385     updateObjBrowser();
386
387     // Find created toolbars
388     QCoreApplication::processEvents();
389
390     QList<QToolBar*> allToolbars = aDesktop->findChildren<QToolBar*>();
391     foreach(QToolBar* aBar, allToolbars) {
392       if (!foreignToolbars.contains(aBar)) {
393         myToolbars[aBar] = true;
394         myToolbarBreaks[aBar] = false;
395         aBar->setVisible(false);
396         aBar->toggleViewAction()->setVisible(false);
397       }
398     }
399     //}
400
401   updateMacros();
402  
403   // we need to start trace after connection is done
404   connect(pqApplicationCore::instance()->getObjectBuilder(), SIGNAL(finishedAddingServer(pqServer*)), 
405           this, SLOT(onFinishedAddingServer(pqServer*)));
406
407   SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr();
408   bool isStop = aResourceMgr->booleanValue( "PARAVIS", "stop_trace", false );
409   // start timer to activate trace in a proper moment
410   if(!isStop) 
411     startTimer( 50 );
412
413   this->VTKConnect = vtkEventQtSlotConnect::New();
414   vtkProcessModule* pm = vtkProcessModule::GetProcessModule();
415
416   this->VTKConnect->Connect(pm, vtkCommand::StartEvent,
417     this, SLOT(onStartProgress()));
418   this->VTKConnect->Connect(pm, vtkCommand::EndEvent,
419     this, SLOT(onEndProgress()));
420 }
421
422 void PVGUI_Module::onStartProgress()
423 {
424   QApplication::setOverrideCursor(Qt::WaitCursor);
425 }
426
427 void PVGUI_Module::onEndProgress()
428 {
429   QApplication::restoreOverrideCursor();
430 }
431
432 void PVGUI_Module::onFinishedAddingServer(pqServer* /*server*/)
433 {
434   SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr();
435   bool isStop = aResourceMgr->booleanValue( "PARAVIS", "stop_trace", false );
436   if(!isStop) 
437     startTimer( 50 );
438 }
439
440 /*!
441   \brief Launches a tracing of current server
442 */
443 void PVGUI_Module::timerEvent(QTimerEvent* te )
444 {
445 #ifndef WNT
446   PyInterp_Dispatcher* aDispatcher = PyInterp_Dispatcher::Get();
447   if ( !aDispatcher->IsBusy() ) {
448     pqPythonManager* manager = qobject_cast<pqPythonManager*>
449       ( pqApplicationCore::instance()->manager( "PYTHON_MANAGER" ) );
450     if ( manager )  {
451       pqPythonDialog* pyDiag = manager->pythonShellDialog();
452       if ( pyDiag ) {
453         pqPythonShell* shell = pyDiag->shell();
454         if ( shell ) {
455           QString script = "from paraview import smtrace\nsmtrace.start_trace()\n";
456           shell->executeScript(script);
457           killTimer( te->timerId() );
458         }
459       }
460     }
461   }
462 #endif
463 }
464   
465 void PVGUI_Module::updateMacros()
466 {
467   pqPythonManager* aPythonManager = pqPVApplicationCore::instance()->pythonManager();
468   if(!aPythonManager)  {
469     return;
470   }
471   
472   QString aRootDir = getenv("PARAVIS_ROOT_DIR");
473
474   QString aSourcePath = aRootDir + "/bin/salome/Macro";
475
476   QStringList aFilter;
477   aFilter << "*.py";
478
479   QDir aSourceDir(aSourcePath);
480   QStringList aSourceFiles = aSourceDir.entryList(aFilter, QDir::Files);
481   foreach (QString aStr, aSourceFiles) {
482     aPythonManager->addMacro(aSourcePath + "/" + aStr);
483   }
484 }
485
486
487 /*!
488   \brief Get list of compliant dockable GUI elements
489   \param m map to be filled in ("type":"default_position")
490 */
491 void PVGUI_Module::windows( QMap<int, int>& m ) const
492 {
493   m.insert( LightApp_Application::WT_ObjectBrowser, Qt::LeftDockWidgetArea );
494   m.insert( LightApp_Application::WT_PyConsole, Qt::BottomDockWidgetArea );
495   // ParaView diagnostic output redirected here
496   m.insert( LightApp_Application::WT_LogWindow, Qt::BottomDockWidgetArea );
497 }
498
499 /*!
500   \brief Static method, performs initialization of ParaView session.
501   \return \c true if ParaView has been initialized successfully, otherwise false
502 */
503 bool PVGUI_Module::pvInit()
504 {
505   //  if ( !pqImplementation::Core ){
506   if ( ! MyCoreApp) {
507     // Obtain command-line arguments
508     int argc = 0;
509     char** argv = 0;
510     QString aOptions = getenv("PARAVIS_OPTIONS");
511     QStringList aOptList = aOptions.split(":", QString::SkipEmptyParts);
512     argv = new char*[aOptList.size() + 1];
513     QStringList args = QApplication::arguments();
514     argv[0] = (args.size() > 0)? strdup(args[0].toLatin1().constData()) : strdup("paravis");
515     argc++;
516
517     foreach (QString aStr, aOptList) {
518       argv[argc] = strdup( aStr.toLatin1().constData() );
519       argc++;
520     }
521     MyCoreApp = new pqPVApplicationCore (argc, argv);
522     if (MyCoreApp->getOptions()->GetHelpSelected() ||
523         MyCoreApp->getOptions()->GetUnknownArgument() ||
524         MyCoreApp->getOptions()->GetErrorMessage() ||
525         MyCoreApp->getOptions()->GetTellVersion()) {
526       return false;
527       }
528
529     // Not sure why this is needed. Andy added this ages ago with comment saying
530     // needed for Mac apps. Need to check that it's indeed still required.
531     QDir dir(QApplication::applicationDirPath());
532     dir.cdUp();
533     dir.cd("Plugins");
534     QApplication::addLibraryPath(dir.absolutePath());
535     // Load required application plugins.
536     QString plugin_string = "";
537     QStringList plugin_list = plugin_string.split(';',QString::SkipEmptyParts);
538     pqBrandPluginsLoader loader;
539     if (loader.loadPlugins(plugin_list) == false) {
540       printf("Failed to load required plugins for this application\n");
541       return false;
542     }
543
544     // Load optional plugins.
545     plugin_string = "";
546     plugin_list = plugin_string.split(';',QString::SkipEmptyParts);
547     loader.loadPlugins(plugin_list, true); //quietly skip not-found plugins.
548
549     // End of Initializer code
550
551     vtkOutputWindow::SetInstance(PVGUI_OutputWindowAdapter::New());
552     
553     new pqTabbedMultiViewWidget(); // it registers as "MULTIVIEW_WIDGET on creation
554     
555     for (int i = 0; i < argc; i++)
556       free(argv[i]);
557     delete[] argv;
558   }
559   
560   return true;
561 }
562  
563 /*!
564   \brief Shows (toShow = true) or hides ParaView view window
565 */
566 void PVGUI_Module::showView( bool toShow )
567 {
568   SalomeApp_Application* anApp = getApp();
569   PVGUI_ViewManager* viewMgr =
570     dynamic_cast<PVGUI_ViewManager*>( anApp->getViewManager( PVGUI_Viewer::Type(), false ) );
571   if ( !viewMgr ) {
572     viewMgr = new PVGUI_ViewManager( anApp->activeStudy(), anApp->desktop() );
573     anApp->addViewManager( viewMgr );
574     connect( viewMgr, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
575              anApp, SLOT( onCloseView( SUIT_ViewManager* ) ) );
576   }
577
578   PVGUI_ViewWindow* pvWnd = dynamic_cast<PVGUI_ViewWindow*>( viewMgr->getActiveView() );
579   if ( !pvWnd ) {
580     pvWnd = dynamic_cast<PVGUI_ViewWindow*>( viewMgr->createViewWindow() );
581   }
582
583   pvWnd->setShown( toShow );
584   if ( toShow ) pvWnd->setFocus();
585 }
586
587 /*!
588   \brief Slot to show help for proxy.
589 */
590 void PVGUI_Module::showHelpForProxy( const QString& groupname, const QString& proxyname )
591 {
592   pqHelpReaction::showProxyHelp(groupname, proxyname);
593 }
594
595
596 /*!
597   \brief Slot to show the waiting state.
598 */
599 void PVGUI_Module::onPreAccept()
600 {
601   getApp()->desktop()->statusBar()->showMessage(tr("STB_PREACCEPT"));
602   QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
603 }
604
605 /*!
606   \brief Slot to show the ready state.
607 */
608 void PVGUI_Module::onPostAccept()
609 {
610   getApp()->desktop()->statusBar()->showMessage(tr("STB_POSTACCEPT"), 2000);
611   QTimer::singleShot(0, this, SLOT(endWaitCursor()));
612 }
613
614 /*!
615   \brief Slot to switch off wait cursor.
616 */
617 void PVGUI_Module::endWaitCursor()
618 {
619   QApplication::restoreOverrideCursor();
620 }
621
622 /*!
623   \brief Returns the ParaView multi-view manager.
624 */
625 pqTabbedMultiViewWidget* PVGUI_Module::getMultiViewManager() const
626 {
627   return qobject_cast<pqTabbedMultiViewWidget*>(pqApplicationCore::instance()->manager("MULTIVIEW_WIDGET"));
628 }
629
630
631 static void ParavisMessageOutput(QtMsgType type, const char *msg)
632 {
633   switch(type)
634     {
635   case QtDebugMsg:
636     vtkOutputWindow::GetInstance()->DisplayText(msg);
637     break;
638   case QtWarningMsg:
639     vtkOutputWindow::GetInstance()->DisplayErrorText(msg);
640     break;
641   case QtCriticalMsg:
642     vtkOutputWindow::GetInstance()->DisplayErrorText(msg);
643     break;
644   case QtFatalMsg:
645     vtkOutputWindow::GetInstance()->DisplayErrorText(msg);
646     break;
647     }
648 }
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   bool isDone = SalomeApp_Module::activateModule( study );
663   if ( !isDone ) return false;
664
665   showView( true );
666   if ( mySourcesMenuId != -1 ) menuMgr()->show(mySourcesMenuId);
667   if ( myFiltersMenuId != -1 ) menuMgr()->show(myFiltersMenuId);
668   if ( myFiltersMenuId != -1 ) menuMgr()->show(myMacrosMenuId);
669   if ( myFiltersMenuId != -1 ) menuMgr()->show(myToolbarsMenuId);
670   setMenuShown( true );
671   setToolShown( true );
672
673   restoreDockWidgetsState();
674
675    QMenu* aMenu = menuMgr()->findMenu( myRecentMenuId );
676    if(aMenu) {
677       QList<QAction*> anActns = aMenu->actions();
678       for (int i = 0; i < anActns.size(); ++i) {
679               QAction* a = anActns.at(i);
680         if(a)
681            a->setVisible(true);
682       }
683     }
684
685   if ( myRecentMenuId != -1 ) menuMgr()->show(myRecentMenuId);
686
687   return isDone;
688 }
689
690
691 /*!
692   \brief Deactivate module.
693   \param study current study
694   \return \c true if deactivaion is done successfully or 0 to prevent
695   deactivation on error
696 */
697 bool PVGUI_Module::deactivateModule( SUIT_Study* study )
698 {
699    QMenu* aMenu = menuMgr()->findMenu( myRecentMenuId );
700    if(aMenu) {
701       QList<QAction*> anActns = aMenu->actions();
702       for (int i = 0; i < anActns.size(); ++i) {
703               QAction* a = anActns.at(i);
704         if(a)
705           a->setVisible(false);
706       }
707     }
708
709   QList<QDockWidget*> aStreamingViews = application()->desktop()->findChildren<QDockWidget*>("pqStreamingControls");
710   foreach(QDockWidget* aView, aStreamingViews) {
711     if (!myDockWidgets.contains(aView))
712       myDockWidgets[aView] = aView->isVisible();
713   }
714
715   /*if (pqImplementation::helpWindow) {
716     pqImplementation::helpWindow->hide();
717     }*/
718   showView( false );
719   // hide menus
720   menuMgr()->hide(myRecentMenuId);
721   menuMgr()->hide(mySourcesMenuId);
722   menuMgr()->hide(myFiltersMenuId);
723   menuMgr()->hide(myMacrosMenuId);
724   menuMgr()->hide(myToolbarsMenuId);
725   setMenuShown( false );
726   setToolShown( false );
727
728
729   saveDockWidgetsState();
730
731   if (myOldMsgHandler)
732     qInstallMsgHandler(myOldMsgHandler);
733
734   return SalomeApp_Module::deactivateModule( study );
735 }
736
737
738 /*!
739   \brief Called when application is closed.
740
741   Process finalize application functionality from ParaView in order to save server settings
742   and nullify application pointer if the application is being closed.
743
744   \param theApp application
745 */
746 void PVGUI_Module::onApplicationClosed( SUIT_Application* theApp )
747 {
748   pqApplicationCore::instance()->settings()->sync();
749   int aAppsNb = SUIT_Session::session()->applications().size();
750   if (aAppsNb == 1) {
751     deleteTemporaryFiles();
752     MyCoreApp->deleteLater();
753   }
754   CAM_Module::onApplicationClosed(theApp);
755 }
756
757
758 /*!
759   \brief Called when study is closed.
760
761   Removes data model from the \a study.
762
763   \param study study being closed
764 */
765 void PVGUI_Module::studyClosed(SUIT_Study* study)
766 {
767   clearParaviewState();
768
769   SalomeApp_Module::studyClosed(study);
770 }
771
772 /*!
773   \brief Called when study is opened.
774 */
775 void PVGUI_Module::onModelOpened()
776 {
777   _PTR(Study) studyDS = PARAVIS::GetCStudy(this);
778   if(!studyDS) {
779     return;
780   }
781   
782   _PTR(SComponent) paravisComp = 
783     studyDS->FindComponent(PARAVIS::GetParavisGen(this)->ComponentDataType());
784   if(!paravisComp) {
785     return;
786   }
787
788   _PTR(ChildIterator) anIter(studyDS->NewChildIterator(paravisComp));
789   for (; anIter->More(); anIter->Next()) {
790     _PTR(SObject) aSObj = anIter->Value();
791     _PTR(GenericAttribute) anAttr;
792     if (!aSObj->FindAttribute(anAttr, "AttributeLocalID")) {
793       continue;
794     }
795     _PTR(AttributeLocalID) anID(anAttr);
796     if (anID->Value() == PVSTATEID) {
797       myStateCounter++;
798     }
799   }
800 }
801
802 /*!
803   \brief Returns IOR of current engine
804 */
805 QString PVGUI_Module::engineIOR() const
806 {
807   CORBA::String_var anIOR = PARAVIS::GetParavisGen(this)->GetIOR();
808   return QString(anIOR.in());
809 }
810
811
812 /*!
813   \brief Open file of format supported by ParaView
814 */
815 void PVGUI_Module::openFile(const char* theName)
816 {
817   QStringList aFiles;
818   aFiles<<theName;
819   pqLoadDataReaction::loadData(aFiles);
820 }
821
822 void PVGUI_Module::executeScript(const char *script)
823 {
824 #ifndef WNT
825   pqPythonManager* manager = qobject_cast<pqPythonManager*>(
826                              pqApplicationCore::instance()->manager("PYTHON_MANAGER"));
827   if (manager)  {
828     pqPythonDialog* pyDiag = manager->pythonShellDialog();
829     if (pyDiag) {
830       pyDiag->runString(script);  
831       }
832     }
833 #endif
834 }
835
836 /*!
837   \brief Returns trace string
838 */
839 static const QString MYReplaceStr("paraview.simple");
840 static const QString MYReplaceImportStr("except: from pvsimple import *");
841 QString PVGUI_Module::getTraceString()
842 {
843   QString traceString;
844 #ifndef WNT
845   pqPythonManager* manager = qobject_cast<pqPythonManager*>(
846                              pqApplicationCore::instance()->manager("PYTHON_MANAGER"));
847   if (manager)  {
848     pqPythonDialog* pyDiag = manager->pythonShellDialog();
849     if (pyDiag) {
850       pyDiag->runString("from paraview import smtrace\n"
851                         "__smtraceString = smtrace.get_trace_string()\n");
852       pyDiag->shell()->makeCurrent();
853       PyObject* main_module = PyImport_AddModule((char*)"__main__");
854       PyObject* global_dict = PyModule_GetDict(main_module);
855       PyObject* string_object = PyDict_GetItemString(global_dict, "__smtraceString");
856       char* string_ptr = string_object ? PyString_AsString(string_object) : 0;
857       if (string_ptr)  {
858         traceString = string_ptr;
859       }
860       pyDiag->shell()->releaseControl();
861     }
862   }
863   if ((!traceString.isNull()) && traceString.length() != 0) {
864     int aPos = traceString.indexOf(MYReplaceStr);
865     while (aPos != -1) {
866       traceString = traceString.replace(aPos, MYReplaceStr.length(), "pvsimple");
867       aPos = traceString.indexOf(MYReplaceStr, aPos);
868     }
869     int aImportPos = traceString.indexOf(MYReplaceImportStr);
870     if(aImportPos != -1)
871       {
872       traceString = traceString.replace(aImportPos, MYReplaceImportStr.length(), "except:\n  import pvsimple\n  from pvsimple import *");
873       }
874   }
875 #endif
876   return traceString;
877 }
878
879 /*!
880   \brief Saves trace string to disk file
881 */
882 void PVGUI_Module::saveTrace(const char* theName)
883 {
884   QFile file(theName);
885   if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
886     MESSAGE( "Could not open file:" << theName );
887     return;
888   }
889   QTextStream out(&file);
890   out << getTraceString();
891   file.close();
892 }
893
894 /*!
895   \brief Saves ParaView state to a disk file
896 */
897 void PVGUI_Module::saveParaviewState(const char* theFileName)
898 {
899   pqApplicationCore::instance()->saveState(theFileName);
900 }
901
902 /*!
903   \brief Delete all objects for Paraview Pipeline Browser
904 */
905 void PVGUI_Module::clearParaviewState()
906 {
907   QAction* deleteAllAction = action(DeleteAllId);
908   if (deleteAllAction) {
909     deleteAllAction->activate(QAction::Trigger);
910   }
911 }
912
913 /*!
914   \brief Restores ParaView state from a disk file
915
916   If toClear == true, the current ojects will be deleted
917 */
918 void PVGUI_Module::loadParaviewState(const char* theFileName)
919 {
920   pqApplicationCore::instance()->loadState(theFileName, getActiveServer());
921 }
922
923 /*!
924   \brief Imports MED data from VISU module by data entry
925 */
926 void PVGUI_Module::onImportFromVisu(QString theEntry)
927 {
928 #ifdef WITH_VISU
929   SUIT_OverrideCursor aWaitCursor;
930
931   // get active study
932   SalomeApp_Study* activeStudy = dynamic_cast<SalomeApp_Study*>(application()->activeStudy());
933   if(!activeStudy) return;
934
935   // get SALOMEDS client study 
936   _PTR(Study) aStudy = activeStudy->studyDS();
937   if(!aStudy) return;
938
939   // find VISU component in a study
940   _PTR(SComponent) aVisuComp = aStudy->FindComponent( "VISU" );
941   if(!aVisuComp) return;
942
943   // get SObject client by entry
944   _PTR(SObject) aSObj = aStudy->FindObjectID(qPrintable(theEntry));
945   if (!aSObj) return;
946
947   // get CORBA SObject
948   SALOMEDS_SObject* aSObject = _CAST(SObject, aSObj);
949   if ( !aSObject ) return;
950
951   // load VISU engine
952   SALOME_NamingService* aNamingService = SalomeApp_Application::namingService();
953   SALOME_LifeCycleCORBA aLCC(aNamingService);
954
955   Engines::EngineComponent_var aComponent = aLCC.FindOrLoad_Component("FactoryServer","VISU");
956   VISU::VISU_Gen_var aVISU = VISU::VISU_Gen::_narrow(aComponent);
957   if(CORBA::is_nil(aVISU)) return;
958
959   _PTR(StudyBuilder) aStudyBuilder = aStudy->NewBuilder();
960   aStudyBuilder->LoadWith( aVisuComp, SalomeApp_Application::orb()->object_to_string(aVISU) );
961
962   // get VISU result object
963   CORBA::Object_var aResultObject = aSObject->GetObject();
964   if (CORBA::is_nil(aResultObject)) return;
965   VISU::Result_var aResult = VISU::Result::_narrow( aResultObject );
966   if (CORBA::is_nil(aResult)) return;
967
968   // export VISU result to the MED file
969   std::string aTmpDir = SALOMEDS_Tool::GetTmpDir();
970   std::string aFileName = aSObject->GetName();
971   std::string aFilePath = aTmpDir + aFileName;
972
973   if (aResult->ExportMED(aFilePath.c_str())) {
974     openFile(aFilePath.c_str());
975     myTemporaryFiles.append(QString(aFilePath.c_str()));
976   }
977 #else
978   MESSAGE("Visu module is not found.");
979 #endif
980 }
981
982 /*!
983   \brief Deletes temporary files created during import operation from VISU
984 */
985 void PVGUI_Module::deleteTemporaryFiles()
986 {
987   foreach(QString aFile, myTemporaryFiles) {
988     if (QFile::exists(aFile)) {
989       QFile::remove(aFile);
990     }
991   }
992 }
993
994
995 /*!
996   \brief Returns current active ParaView server
997 */
998 pqServer* PVGUI_Module::getActiveServer()
999 {
1000   return pqApplicationCore::instance()->getActiveServer();
1001 }
1002
1003
1004 /*!
1005   \brief Creates PARAVIS preference pane 
1006 */
1007 void PVGUI_Module::createPreferences()
1008 {
1009   // Paraview settings tab
1010   int aParaViewSettingsTab = addPreference( tr( "TIT_PVIEWSETTINGS" ) );
1011   int aPanel = addPreference(QString(), aParaViewSettingsTab, LightApp_Preferences::UserDefined, "PARAVIS", "");
1012   setPreferenceProperty(aPanel, "content", (qint64)(new PVGUI_ParaViewSettingsPane()));
1013
1014   // Paravis settings tab
1015   int aParaVisSettingsTab = addPreference( tr( "TIT_PVISSETTINGS" ) );
1016   addPreference( tr( "PREF_STOP_TRACE" ), aParaVisSettingsTab, LightApp_Preferences::Bool, "PARAVIS", "stop_trace");
1017
1018   int aSaveType = addPreference(tr( "PREF_SAVE_TYPE_LBL" ), aParaVisSettingsTab,
1019                                 LightApp_Preferences::Selector,
1020                                 "PARAVIS", "savestate_type");
1021   QList<QVariant> aIndices;
1022   QStringList aStrings;
1023   aIndices<<0<<1<<2;
1024   aStrings<<tr("PREF_SAVE_TYPE_0");
1025   aStrings<<tr("PREF_SAVE_TYPE_1");
1026   aStrings<<tr("PREF_SAVE_TYPE_2");
1027   setPreferenceProperty(aSaveType, "strings", aStrings);
1028   setPreferenceProperty(aSaveType, "indexes", aIndices);
1029 }
1030
1031 /*!
1032   \brief Creates ParaViS context menu popup
1033 */
1034 void PVGUI_Module::contextMenuPopup(const QString& theClient, QMenu* theMenu, QString& theTitle)
1035 {
1036   SalomeApp_Module::contextMenuPopup(theClient, theMenu, theTitle);
1037   
1038   // Check if we are in Object Browser
1039   SUIT_DataBrowser* ob = getApp()->objectBrowser();
1040   bool isOBClient = (ob && theClient == ob->popupClientType());
1041   if (!isOBClient) {
1042     return;
1043   }
1044
1045   // Get list of selected objects
1046   LightApp_SelectionMgr* aSelectionMgr = getApp()->selectionMgr();
1047   SALOME_ListIO aListIO;
1048   aSelectionMgr->selectedObjects(aListIO);
1049   if (aListIO.Extent() == 1 && aListIO.First()->hasEntry()) {
1050     QString entry = QString(aListIO.First()->getEntry());
1051     
1052     // Get active study
1053     SalomeApp_Study* activeStudy = 
1054       dynamic_cast<SalomeApp_Study*>(getApp()->activeStudy());
1055     if(!activeStudy) {
1056       return;
1057     }
1058
1059     // Get SALOMEDS client study 
1060     _PTR(Study) studyDS = activeStudy->studyDS();
1061     if(!studyDS) {
1062       return;
1063     }
1064
1065     QString paravisDataType(PARAVIS::GetParavisGen(this)->ComponentDataType());
1066     if(activeStudy && activeStudy->isComponent(entry) && 
1067        activeStudy->componentDataType(entry) == paravisDataType) {
1068       // ParaViS module object
1069       theMenu->addSeparator();
1070       theMenu->addAction(action(SaveStatePopupId));
1071     }
1072     else {
1073       // Try to get state object
1074       _PTR(SObject) stateSObj = 
1075         studyDS->FindObjectID(entry.toLatin1().constData());
1076       if (!stateSObj) {
1077         return;
1078       }
1079       
1080       // Check local id
1081       _PTR(GenericAttribute) anAttr;
1082       if (!stateSObj->FindAttribute(anAttr, "AttributeLocalID")) {
1083         return;
1084       }
1085
1086       _PTR(AttributeLocalID) anID(anAttr);
1087       
1088       if (anID->Value() == PVSTATEID) {
1089         // Paraview state object
1090         theMenu->addSeparator();
1091         theMenu->addAction(action(AddStatePopupId));
1092         theMenu->addAction(action(CleanAndAddStatePopupId));
1093         theMenu->addSeparator();
1094         theMenu->addAction(action(ParaVisRenameId));
1095         theMenu->addAction(action(ParaVisDeleteId));
1096       }
1097     }
1098   }
1099 }
1100
1101 void PVGUI_Module::onShowTrace()
1102 {
1103   if (!myTraceWindow) {
1104     myTraceWindow = new pqPythonScriptEditor(getApp()->desktop());
1105   }
1106   myTraceWindow->setText(getTraceString());
1107   myTraceWindow->show();
1108   myTraceWindow->raise();
1109   myTraceWindow->activateWindow();
1110 }
1111
1112 /*!
1113   \brief Show ParaView view.
1114 */
1115 void PVGUI_Module::onNewParaViewWindow()
1116 {
1117   showView(true);
1118 }
1119
1120 /*!
1121   \brief Save state under the module root object.
1122 */
1123 void PVGUI_Module::onSaveMultiState()
1124 {
1125   // Create state study object
1126   
1127   // Get SALOMEDS client study
1128   _PTR(Study) studyDS = PARAVIS::GetCStudy(this);
1129   if(!studyDS) {
1130     return;
1131   }
1132   
1133   _PTR(SComponent) paravisComp = 
1134     studyDS->FindComponent(PARAVIS::GetParavisGen(this)->ComponentDataType());
1135   if(!paravisComp) {
1136     return;
1137   }
1138
1139   // Unlock the study if it is locked
1140   bool isLocked = studyDS->GetProperties()->IsLocked();
1141   if (isLocked) {
1142     studyDS->GetProperties()->SetLocked(false);
1143   }
1144   
1145   QString stateName = tr("SAVED_PARAVIEW_STATE_NAME") + 
1146     QString::number(myStateCounter + 1);
1147
1148   _PTR(StudyBuilder) studyBuilder = studyDS->NewBuilder();
1149   _PTR(SObject) newSObj = studyBuilder->NewObject(paravisComp);
1150
1151   // Set name
1152   _PTR(GenericAttribute) anAttr;
1153   anAttr = studyBuilder->FindOrCreateAttribute(newSObj, "AttributeName");
1154   _PTR(AttributeName) nameAttr(anAttr);
1155   
1156   nameAttr->SetValue(stateName.toLatin1().constData());
1157
1158   // Set local id
1159   anAttr = studyBuilder->FindOrCreateAttribute(newSObj, "AttributeLocalID");
1160   _PTR(AttributeLocalID) localIdAttr(anAttr);
1161   
1162   localIdAttr->SetValue(PVSTATEID);
1163
1164   // Set file name
1165   QString stateEntry = QString::fromStdString(newSObj->GetID());
1166  
1167   // File name for state saving
1168   QString tmpDir = QString::fromStdString(SALOMEDS_Tool::GetTmpDir());
1169   QString fileName = QString("%1_paravisstate:%2").arg(tmpDir, 
1170                                                        stateEntry);
1171
1172   anAttr = studyBuilder->FindOrCreateAttribute(newSObj, "AttributeString");
1173   _PTR(AttributeString) stringAttr(anAttr);
1174   
1175   stringAttr->SetValue(fileName.toLatin1().constData());
1176
1177   // Lock the study back if necessary
1178   if (isLocked) {
1179     studyDS->GetProperties()->SetLocked(true);
1180   }
1181   
1182   // Save state
1183   saveParaviewState(fileName.toLatin1().constData());
1184   myTemporaryFiles.append(fileName);
1185   
1186   // Increment the counter
1187   myStateCounter++;
1188
1189   updateObjBrowser();
1190 }
1191
1192 /*!
1193   \brief Restore the selected state by merging with the current one.
1194 */
1195 void PVGUI_Module::onAddState()
1196 {
1197   loadSelectedState(false);
1198 }
1199
1200 /*!
1201   \brief Clean the current state and restore the selected one.
1202 */
1203 void PVGUI_Module::onCleanAddState()
1204 {
1205   loadSelectedState(true);
1206 }
1207
1208 /*!
1209   \brief Rename the selected object.
1210 */
1211 void PVGUI_Module::onRename()
1212 {
1213   LightApp_SelectionMgr* aSelectionMgr = getApp()->selectionMgr();
1214   SALOME_ListIO aListIO;
1215   aSelectionMgr->selectedObjects(aListIO);
1216   
1217   if (aListIO.Extent() == 1 && aListIO.First()->hasEntry()) {
1218     std::string entry = aListIO.First()->getEntry();
1219     
1220     // Get SALOMEDS client study 
1221     _PTR(Study) studyDS = PARAVIS::GetCStudy(this);
1222     if(!studyDS) {
1223       return;
1224     }
1225     
1226     // Unlock the study if it is locked
1227     bool isLocked = studyDS->GetProperties()->IsLocked();
1228     if (isLocked) {
1229       studyDS->GetProperties()->SetLocked(false);
1230     }
1231     
1232     // Rename the selected state object
1233     _PTR(SObject) stateSObj = studyDS->FindObjectID(entry);
1234     if (!stateSObj) {
1235       return;
1236     }
1237     
1238     _PTR(GenericAttribute) anAttr;
1239     if (stateSObj->FindAttribute(anAttr, "AttributeName")) {
1240       _PTR(AttributeName) nameAttr (anAttr);
1241       QString newName = 
1242         LightApp_NameDlg::getName(getApp()->desktop(), nameAttr->Value().c_str());
1243       if (!newName.isEmpty()) {
1244         nameAttr->SetValue(newName.toLatin1().constData());
1245         aListIO.First()->setName(newName.toLatin1().constData());
1246       }
1247     }
1248     
1249     // Lock the study back if necessary
1250     if (isLocked) {
1251       studyDS->GetProperties()->SetLocked(true);
1252     }
1253     
1254     // Update object browser
1255     updateObjBrowser();
1256     
1257   }
1258 }
1259
1260 /*!
1261   \brief Delete the selected objects.
1262 */
1263 void PVGUI_Module::onDelete()
1264 {
1265   LightApp_SelectionMgr* aSelectionMgr = getApp()->selectionMgr();
1266   SALOME_ListIO aListIO;
1267   aSelectionMgr->selectedObjects(aListIO);
1268   
1269   if (aListIO.Extent() == 1 && aListIO.First()->hasEntry()) {
1270     std::string entry = aListIO.First()->getEntry();
1271     
1272     // Get SALOMEDS client study 
1273     _PTR(Study) studyDS = PARAVIS::GetCStudy(this);
1274     if(!studyDS) {
1275       return;
1276     }
1277     
1278     // Unlock the study if it is locked
1279     bool isLocked = studyDS->GetProperties()->IsLocked();
1280     if (isLocked) {
1281       studyDS->GetProperties()->SetLocked(false);
1282     }
1283     
1284     // Remove the selected state from the study
1285     _PTR(StudyBuilder) studyBuilder = studyDS->NewBuilder();
1286     _PTR(SObject) stateSObj = studyDS->FindObjectID(entry);
1287     studyBuilder->RemoveObject(stateSObj);
1288     
1289     // Lock the study back if necessary
1290     if (isLocked) {
1291       studyDS->GetProperties()->SetLocked(true);
1292     }
1293     
1294     // Update object browser
1295     updateObjBrowser();
1296   }
1297 }
1298
1299 /*!
1300   \brief Discover help project files from the resources.
1301   \return name of the help file. 
1302 */
1303 QString PVGUI_Module::getHelpFileName() {
1304   QString aPVHome(getenv("PVHOME"));
1305   if (aPVHome.isNull()) {
1306     qWarning("Wariable PVHOME is not defined");
1307     return QString();
1308   }
1309   QChar aSep = QDir::separator();
1310   //PARAVIEW_VERSION from the vtkPVConfig.h file
1311   QString aFileName =  aPVHome + aSep + "share" + aSep + "doc" + aSep + "paraview-"+ PARAVIEW_VERSION + aSep + "paraview.qch";
1312   return aFileName;
1313 }
1314
1315
1316 /*!
1317   \brief Load selected paraview state
1318
1319   If toClear == true, the current state will be cleared
1320 */
1321 void PVGUI_Module::loadSelectedState(bool toClear)
1322 {
1323   QString fileName;
1324
1325   LightApp_SelectionMgr* aSelectionMgr = getApp()->selectionMgr();
1326   SALOME_ListIO aListIO;
1327   aSelectionMgr->selectedObjects(aListIO);
1328   
1329   if (aListIO.Extent() == 1 && aListIO.First()->hasEntry()) {
1330     std::string entry = aListIO.First()->getEntry();
1331     
1332     // Get SALOMEDS client study 
1333     _PTR(Study) studyDS = PARAVIS::GetCStudy(this);
1334     if(!studyDS) {
1335       return;
1336     }
1337
1338     // Check local id
1339     _PTR(SObject) stateSObj = studyDS->FindObjectID(entry);
1340     _PTR(GenericAttribute) anAttr;
1341     if (!stateSObj->FindAttribute(anAttr, "AttributeLocalID")) {
1342       return;
1343     }
1344     _PTR(AttributeLocalID) anID(anAttr);
1345     if (!anID->Value() == PVSTATEID) {
1346       return;
1347     }
1348
1349     // Get state file name
1350     if (stateSObj->FindAttribute(anAttr, "AttributeString")) {
1351       _PTR(AttributeString) aStringAttr(anAttr);
1352       QString stringValue(aStringAttr->Value().c_str());
1353
1354       if (QFile::exists(stringValue)) {
1355         fileName = stringValue;
1356       }
1357     }
1358   }
1359   
1360   if (!fileName.isEmpty()) {
1361     if (toClear) {
1362       clearParaviewState();
1363     }
1364
1365     loadParaviewState(fileName.toLatin1().constData());
1366   } 
1367   else {
1368     SUIT_MessageBox::critical(getApp()->desktop(),
1369                               tr("ERR_ERROR"),
1370                               tr("ERR_STATE_CANNOT_BE_RESTORED"));
1371   }
1372 }
1373
1374 /*!
1375   \fn CAM_Module* createModule();
1376   \brief Export module instance (factory function).
1377   \return new created instance of the module
1378 */
1379
1380 #ifdef WNT
1381 #define PVGUI_EXPORT __declspec(dllexport)
1382 #else   // WNT
1383 #define PVGUI_EXPORT
1384 #endif  // WNT
1385
1386 extern "C" {
1387   PVGUI_EXPORT CAM_Module* createModule() {
1388     return new PVGUI_Module();
1389   }
1390   
1391   PVGUI_EXPORT char* getModuleVersion() {
1392     return (char*)PARAVIS_VERSION_STR;
1393   }
1394           
1395 }