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