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