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