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