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