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