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