Salome HOME
Fix of 0022210: [CEA 816] The keyboard shortcut "ctrl + space" to get a filter does...
[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   bool isDone = SalomeApp_Module::activateModule( study );
865   if ( !isDone ) return false;
866
867   showView( true );
868   if ( mySourcesMenuId != -1 ) menuMgr()->show(mySourcesMenuId);
869   if ( myFiltersMenuId != -1 ) menuMgr()->show(myFiltersMenuId);
870   if ( myFiltersMenuId != -1 ) menuMgr()->show(myMacrosMenuId);
871   if ( myFiltersMenuId != -1 ) menuMgr()->show(myToolbarsMenuId);
872   setMenuShown( true );
873   setToolShown( true );
874
875   restoreDockWidgetsState();
876
877   QMenu* aMenu = menuMgr()->findMenu( myRecentMenuId );
878   if(aMenu) {
879     QList<QAction*> anActns = aMenu->actions();
880     for (int i = 0; i < anActns.size(); ++i) {
881       QAction* a = anActns.at(i);
882       if(a)
883         a->setVisible(true);
884     }
885   }
886
887   QList<QMenu*>::iterator it;
888   for (it = myMenus.begin(); it != myMenus.end(); ++it) {
889     QAction* a = (*it)->menuAction();
890     if(a)
891       a->setVisible(true);
892   }
893
894   if ( myRecentMenuId != -1 ) menuMgr()->show(myRecentMenuId);
895
896   ClientFindOrCreateParavisComponent(PARAVIS::GetCStudy(this));
897
898   return isDone;
899 }
900
901
902 /*!
903   \brief Deactivate module.
904   \param study current study
905   \return \c true if deactivaion is done successfully or 0 to prevent
906   deactivation on error
907 */
908 bool PVGUI_Module::deactivateModule( SUIT_Study* study )
909 {
910   QMenu* aMenu = menuMgr()->findMenu( myRecentMenuId );
911   if(aMenu) {
912     QList<QAction*> anActns = aMenu->actions();
913     for (int i = 0; i < anActns.size(); ++i) {
914       QAction* a = anActns.at(i);
915       if(a)
916         a->setVisible(false);
917     }
918   }
919
920   QList<QMenu*>::iterator it;
921   for (it = myMenus.begin(); it != myMenus.end(); ++it) {
922     QAction* a = (*it)->menuAction();
923     if(a)
924       a->setVisible(false);
925   }
926
927   QList<QDockWidget*> aStreamingViews = application()->desktop()->findChildren<QDockWidget*>("pqStreamingControls");
928   foreach(QDockWidget* aView, aStreamingViews) {
929     if (!myDockWidgets.contains(aView))
930       myDockWidgets[aView] = aView->isVisible();
931   }
932
933   /*if (pqImplementation::helpWindow) {
934     pqImplementation::helpWindow->hide();
935     }*/
936   showView( false );
937   // hide menus
938   menuMgr()->hide(myRecentMenuId);
939   menuMgr()->hide(mySourcesMenuId);
940   menuMgr()->hide(myFiltersMenuId);
941   menuMgr()->hide(myMacrosMenuId);
942   menuMgr()->hide(myToolbarsMenuId);
943   setMenuShown( false );
944   setToolShown( false );
945
946
947   saveDockWidgetsState();
948
949   SUIT_ExceptionHandler::removeCleanUpRoutine( paravisCleanUp );
950
951   if (myOldMsgHandler)
952     qInstallMsgHandler(myOldMsgHandler);
953
954   return SalomeApp_Module::deactivateModule( study );
955 }
956
957
958 /*!
959   \brief Called when application is closed.
960
961   Process finalize application functionality from ParaView in order to save server settings
962   and nullify application pointer if the application is being closed.
963
964   \param theApp application
965 */
966 void PVGUI_Module::onApplicationClosed( SUIT_Application* theApp )
967 {
968   pqApplicationCore::instance()->settings()->sync();
969   int aAppsNb = SUIT_Session::session()->applications().size();
970   if (aAppsNb == 1) {
971     deleteTemporaryFiles();
972     MyCoreApp->deleteLater();
973   }
974   CAM_Module::onApplicationClosed(theApp);
975 }
976
977
978 /*!
979   \brief Called when study is closed.
980
981   Removes data model from the \a study.
982
983   \param study study being closed
984 */
985 void PVGUI_Module::studyClosed(SUIT_Study* study)
986 {
987   clearParaviewState();
988
989   SalomeApp_Module::studyClosed(study);
990 }
991
992 /*!
993   \brief Called when study is opened.
994 */
995 void PVGUI_Module::onModelOpened()
996 {
997   _PTR(Study) studyDS = PARAVIS::GetCStudy(this);
998   if(!studyDS) {
999     return;
1000   }
1001   
1002   _PTR(SComponent) paravisComp = 
1003     studyDS->FindComponent(PARAVIS::GetParavisGen(this)->ComponentDataType());
1004   if(!paravisComp) {
1005     return;
1006   }
1007
1008   _PTR(ChildIterator) anIter(studyDS->NewChildIterator(paravisComp));
1009   for (; anIter->More(); anIter->Next()) {
1010     _PTR(SObject) aSObj = anIter->Value();
1011     _PTR(GenericAttribute) anAttr;
1012     if (!aSObj->FindAttribute(anAttr, "AttributeLocalID")) {
1013       continue;
1014     }
1015     _PTR(AttributeLocalID) anID(anAttr);
1016     if (anID->Value() == PVSTATEID) {
1017       myStateCounter++;
1018     }
1019   }
1020 }
1021
1022 /*!
1023   \brief Returns IOR of current engine
1024 */
1025 QString PVGUI_Module::engineIOR() const
1026 {
1027   CORBA::String_var anIOR = PARAVIS::GetParavisGen(this)->GetIOR();
1028   return QString(anIOR.in());
1029 }
1030
1031
1032 /*!
1033   \brief Open file of format supported by ParaView
1034 */
1035 void PVGUI_Module::openFile(const char* theName)
1036 {
1037   QStringList aFiles;
1038   aFiles<<theName;
1039   pqLoadDataReaction::loadData(aFiles);
1040 }
1041
1042 void PVGUI_Module::executeScript(const char *script)
1043 {
1044 #ifndef WNT
1045   pqPythonManager* manager = qobject_cast<pqPythonManager*>(
1046                              pqApplicationCore::instance()->manager("PYTHON_MANAGER"));
1047   if (manager)  {
1048     pqPythonDialog* pyDiag = manager->pythonShellDialog();
1049     if (pyDiag) {
1050       pyDiag->runString(script);  
1051       }
1052     }
1053 #endif
1054 }
1055
1056 /*!
1057   \brief Returns trace string
1058 */
1059 static const QString MYReplaceStr("paraview.simple");
1060 static const QString MYReplaceImportStr("except: from pvsimple import *");
1061 QString PVGUI_Module::getTraceString()
1062 {
1063   QString traceString;
1064 #ifndef WNT
1065   pqPythonManager* manager = qobject_cast<pqPythonManager*>(
1066                              pqApplicationCore::instance()->manager("PYTHON_MANAGER"));
1067   if (manager)  {
1068     pqPythonDialog* pyDiag = manager->pythonShellDialog();
1069     if (pyDiag) {
1070       pyDiag->runString("from paraview import smtrace\n"
1071                         "__smtraceString = smtrace.get_trace_string()\n");
1072       pyDiag->shell()->makeCurrent();
1073       PyObject* main_module = PyImport_AddModule((char*)"__main__");
1074       PyObject* global_dict = PyModule_GetDict(main_module);
1075       PyObject* string_object = PyDict_GetItemString(global_dict, "__smtraceString");
1076       char* string_ptr = string_object ? PyString_AsString(string_object) : 0;
1077       if (string_ptr)  {
1078         traceString = string_ptr;
1079       }
1080       pyDiag->shell()->releaseControl();
1081     }
1082   }
1083   if ((!traceString.isNull()) && traceString.length() != 0) {
1084     int aPos = traceString.indexOf(MYReplaceStr);
1085     while (aPos != -1) {
1086       traceString = traceString.replace(aPos, MYReplaceStr.length(), "pvsimple");
1087       aPos = traceString.indexOf(MYReplaceStr, aPos);
1088     }
1089     int aImportPos = traceString.indexOf(MYReplaceImportStr);
1090     if(aImportPos != -1)
1091       {
1092       traceString = traceString.replace(aImportPos, MYReplaceImportStr.length(), "except:\n  import pvsimple\n  from pvsimple import *");
1093       }
1094   }
1095 #endif
1096   return traceString;
1097 }
1098
1099 /*!
1100   \brief Saves trace string to disk file
1101 */
1102 void PVGUI_Module::saveTrace(const char* theName)
1103 {
1104   QFile file(theName);
1105   if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
1106     MESSAGE( "Could not open file:" << theName );
1107     return;
1108   }
1109   QTextStream out(&file);
1110   out << getTraceString();
1111   file.close();
1112 }
1113
1114 /*!
1115   \brief Saves ParaView state to a disk file
1116 */
1117 void PVGUI_Module::saveParaviewState(const char* theFileName)
1118 {
1119   pqApplicationCore::instance()->saveState(theFileName);
1120 }
1121
1122 /*!
1123   \brief Delete all objects for Paraview Pipeline Browser
1124 */
1125 void PVGUI_Module::clearParaviewState()
1126 {
1127   QAction* deleteAllAction = action(DeleteAllId);
1128   if (deleteAllAction) {
1129     deleteAllAction->activate(QAction::Trigger);
1130   }
1131 }
1132
1133 /*!
1134   \brief Restores ParaView state from a disk file
1135
1136   If toClear == true, the current ojects will be deleted
1137 */
1138 void PVGUI_Module::loadParaviewState(const char* theFileName)
1139 {
1140   pqApplicationCore::instance()->loadState(theFileName, getActiveServer());
1141 }
1142
1143 /*!
1144   \brief Imports MED data from VISU module by data entry
1145 */
1146 void PVGUI_Module::onImportFromVisu(QString theEntry)
1147 {
1148 #ifdef WITH_VISU
1149   SUIT_OverrideCursor aWaitCursor;
1150
1151   // get active study
1152   SalomeApp_Study* activeStudy = dynamic_cast<SalomeApp_Study*>(application()->activeStudy());
1153   if(!activeStudy) return;
1154
1155   // get SALOMEDS client study 
1156   _PTR(Study) aStudy = activeStudy->studyDS();
1157   if(!aStudy) return;
1158
1159   // find VISU component in a study
1160   _PTR(SComponent) aVisuComp = aStudy->FindComponent( "VISU" );
1161   if(!aVisuComp) return;
1162
1163   // get SObject client by entry
1164   _PTR(SObject) aSObj = aStudy->FindObjectID(qPrintable(theEntry));
1165   if (!aSObj) return;
1166
1167   // get CORBA SObject
1168   SALOMEDS_SObject* aSObject = _CAST(SObject, aSObj);
1169   if ( !aSObject ) return;
1170
1171   // load VISU engine
1172   SALOME_NamingService* aNamingService = SalomeApp_Application::namingService();
1173   SALOME_LifeCycleCORBA aLCC(aNamingService);
1174
1175   Engines::EngineComponent_var aComponent = aLCC.FindOrLoad_Component("FactoryServer","VISU");
1176   VISU::VISU_Gen_var aVISU = VISU::VISU_Gen::_narrow(aComponent);
1177   if(CORBA::is_nil(aVISU)) return;
1178
1179   _PTR(StudyBuilder) aStudyBuilder = aStudy->NewBuilder();
1180   aStudyBuilder->LoadWith( aVisuComp, SalomeApp_Application::orb()->object_to_string(aVISU) );
1181
1182   // get VISU result object
1183   CORBA::Object_var aResultObject = aSObject->GetObject();
1184   if (CORBA::is_nil(aResultObject)) return;
1185   VISU::Result_var aResult = VISU::Result::_narrow( aResultObject );
1186   if (CORBA::is_nil(aResult)) return;
1187
1188   // export VISU result to the MED file
1189   std::string aTmpDir = SALOMEDS_Tool::GetTmpDir();
1190   std::string aFileName = aSObject->GetName();
1191   std::string aFilePath = aTmpDir + aFileName;
1192
1193   if (aResult->ExportMED(aFilePath.c_str())) {
1194     openFile(aFilePath.c_str());
1195     myTemporaryFiles.append(QString(aFilePath.c_str()));
1196   }
1197 #else
1198   MESSAGE("Visu module is not found.");
1199 #endif
1200 }
1201
1202 /*!
1203   \brief Deletes temporary files created during import operation from VISU
1204 */
1205 void PVGUI_Module::deleteTemporaryFiles()
1206 {
1207   foreach(QString aFile, myTemporaryFiles) {
1208     if (QFile::exists(aFile)) {
1209       QFile::remove(aFile);
1210     }
1211   }
1212 }
1213
1214
1215 /*!
1216   \brief Returns current active ParaView server
1217 */
1218 pqServer* PVGUI_Module::getActiveServer()
1219 {
1220   return pqApplicationCore::instance()->getActiveServer();
1221 }
1222
1223
1224 /*!
1225   \brief Creates PARAVIS preference pane 
1226 */
1227 void PVGUI_Module::createPreferences()
1228 {
1229   // Paraview settings tab
1230   int aParaViewSettingsTab = addPreference( tr( "TIT_PVIEWSETTINGS" ) );
1231   int aPanel = addPreference(QString(), aParaViewSettingsTab, LightApp_Preferences::UserDefined, "PARAVIS", "");
1232   setPreferenceProperty(aPanel, "content", (qint64)(new PVGUI_ParaViewSettingsPane()));
1233
1234   // Paravis settings tab
1235   int aParaVisSettingsTab = addPreference( tr( "TIT_PVISSETTINGS" ) );
1236   addPreference( tr( "PREF_STOP_TRACE" ), aParaVisSettingsTab, LightApp_Preferences::Bool, "PARAVIS", "stop_trace");
1237
1238   int aSaveType = addPreference(tr( "PREF_SAVE_TYPE_LBL" ), aParaVisSettingsTab,
1239                                 LightApp_Preferences::Selector,
1240                                 "PARAVIS", "savestate_type");
1241   QList<QVariant> aIndices;
1242   QStringList aStrings;
1243   aIndices<<0<<1<<2;
1244   aStrings<<tr("PREF_SAVE_TYPE_0");
1245   aStrings<<tr("PREF_SAVE_TYPE_1");
1246   aStrings<<tr("PREF_SAVE_TYPE_2");
1247   setPreferenceProperty(aSaveType, "strings", aStrings);
1248   setPreferenceProperty(aSaveType, "indexes", aIndices);
1249
1250   //rnv: imp 21712: [CEA 581] Preference to display legend by default 
1251   int aDispColoreLegend = addPreference( tr( "PREF_SHOW_COLOR_LEGEND" ), aParaVisSettingsTab,
1252                                          LightApp_Preferences::Bool, "PARAVIS", "show_color_legend");
1253 }
1254
1255 /*!
1256   \brief Creates ParaViS context menu popup
1257 */
1258 void PVGUI_Module::contextMenuPopup(const QString& theClient, QMenu* theMenu, QString& theTitle)
1259 {
1260   SalomeApp_Module::contextMenuPopup(theClient, theMenu, theTitle);
1261   
1262   // Check if we are in Object Browser
1263   SUIT_DataBrowser* ob = getApp()->objectBrowser();
1264   bool isOBClient = (ob && theClient == ob->popupClientType());
1265   if (!isOBClient) {
1266     return;
1267   }
1268
1269   // Get list of selected objects
1270   LightApp_SelectionMgr* aSelectionMgr = getApp()->selectionMgr();
1271   SALOME_ListIO aListIO;
1272   aSelectionMgr->selectedObjects(aListIO);
1273   if (aListIO.Extent() == 1 && aListIO.First()->hasEntry()) {
1274     QString entry = QString(aListIO.First()->getEntry());
1275     
1276     // Get active study
1277     SalomeApp_Study* activeStudy = 
1278       dynamic_cast<SalomeApp_Study*>(getApp()->activeStudy());
1279     if(!activeStudy) {
1280       return;
1281     }
1282
1283     // Get SALOMEDS client study 
1284     _PTR(Study) studyDS = activeStudy->studyDS();
1285     if(!studyDS) {
1286       return;
1287     }
1288
1289     QString paravisDataType(PARAVIS::GetParavisGen(this)->ComponentDataType());
1290     if(activeStudy && activeStudy->isComponent(entry) && 
1291        activeStudy->componentDataType(entry) == paravisDataType) {
1292       // ParaViS module object
1293       theMenu->addSeparator();
1294       theMenu->addAction(action(SaveStatePopupId));
1295     }
1296     else {
1297       // Try to get state object
1298       _PTR(SObject) stateSObj = 
1299         studyDS->FindObjectID(entry.toLatin1().constData());
1300       if (!stateSObj) {
1301         return;
1302       }
1303       
1304       // Check local id
1305       _PTR(GenericAttribute) anAttr;
1306       if (!stateSObj->FindAttribute(anAttr, "AttributeLocalID")) {
1307         return;
1308       }
1309
1310       _PTR(AttributeLocalID) anID(anAttr);
1311       
1312       if (anID->Value() == PVSTATEID) {
1313         // Paraview state object
1314         theMenu->addSeparator();
1315         theMenu->addAction(action(AddStatePopupId));
1316         theMenu->addAction(action(CleanAndAddStatePopupId));
1317         theMenu->addSeparator();
1318         theMenu->addAction(action(ParaVisRenameId));
1319         theMenu->addAction(action(ParaVisDeleteId));
1320       }
1321     }
1322   }
1323 }
1324
1325 /*!
1326   \brief. Show ParaView python trace.
1327 */
1328 void PVGUI_Module::onShowTrace()
1329 {
1330   if (!myTraceWindow) {
1331     myTraceWindow = new pqPythonScriptEditor(getApp()->desktop());
1332   }
1333   myTraceWindow->setText(getTraceString());
1334   myTraceWindow->show();
1335   myTraceWindow->raise();
1336   myTraceWindow->activateWindow();
1337 }
1338
1339
1340 /*!
1341   \brief. Re-initialize ParaView python trace.
1342 */
1343 void PVGUI_Module::onRestartTrace()
1344 {
1345   PyInterp_Dispatcher* aDispatcher = PyInterp_Dispatcher::Get();
1346   if ( !aDispatcher->IsBusy() ) {
1347     pqPythonManager* manager = qobject_cast<pqPythonManager*>
1348        ( pqApplicationCore::instance()->manager( "PYTHON_MANAGER" ) );
1349     if ( manager )  {
1350       pqPythonDialog* pyDiag = manager->pythonShellDialog();
1351         if ( pyDiag ) {
1352           pqPythonShell* shell = pyDiag->shell();
1353             if ( shell ) {
1354               QString script = "from paraview import smtrace\n";
1355               script += "smtrace.stop_trace()\n";
1356               script += "smtrace.start_trace()\n";
1357               shell->executeScript(script);
1358             }
1359         }
1360     }
1361   }
1362 }
1363
1364 /*!
1365   \brief Show ParaView view.
1366 */
1367 void PVGUI_Module::onNewParaViewWindow()
1368 {
1369   showView(true);
1370 }
1371
1372 /*!
1373   \brief Save state under the module root object.
1374 */
1375 void PVGUI_Module::onSaveMultiState()
1376 {
1377   // Create state study object
1378   
1379   // Get SALOMEDS client study
1380   _PTR(Study) studyDS = PARAVIS::GetCStudy(this);
1381   if(!studyDS) {
1382     return;
1383   }
1384   
1385   _PTR(SComponent) paravisComp = 
1386     studyDS->FindComponent(PARAVIS::GetParavisGen(this)->ComponentDataType());
1387   if(!paravisComp) {
1388     return;
1389   }
1390
1391   // Unlock the study if it is locked
1392   bool isLocked = studyDS->GetProperties()->IsLocked();
1393   if (isLocked) {
1394     studyDS->GetProperties()->SetLocked(false);
1395   }
1396   
1397   QString stateName = tr("SAVED_PARAVIEW_STATE_NAME") + 
1398     QString::number(myStateCounter + 1);
1399
1400   _PTR(StudyBuilder) studyBuilder = studyDS->NewBuilder();
1401   _PTR(SObject) newSObj = studyBuilder->NewObject(paravisComp);
1402
1403   // Set name
1404   _PTR(GenericAttribute) anAttr;
1405   anAttr = studyBuilder->FindOrCreateAttribute(newSObj, "AttributeName");
1406   _PTR(AttributeName) nameAttr(anAttr);
1407   
1408   nameAttr->SetValue(stateName.toLatin1().constData());
1409
1410   // Set local id
1411   anAttr = studyBuilder->FindOrCreateAttribute(newSObj, "AttributeLocalID");
1412   _PTR(AttributeLocalID) localIdAttr(anAttr);
1413   
1414   localIdAttr->SetValue(PVSTATEID);
1415
1416   // Set file name
1417   QString stateEntry = QString::fromStdString(newSObj->GetID());
1418  
1419   // File name for state saving
1420   QString tmpDir = QString::fromStdString(SALOMEDS_Tool::GetTmpDir());
1421   QString fileName = QString("%1_paravisstate:%2").arg(tmpDir, 
1422                                                        stateEntry);
1423
1424   anAttr = studyBuilder->FindOrCreateAttribute(newSObj, "AttributeString");
1425   _PTR(AttributeString) stringAttr(anAttr);
1426   
1427   stringAttr->SetValue(fileName.toLatin1().constData());
1428
1429   // Lock the study back if necessary
1430   if (isLocked) {
1431     studyDS->GetProperties()->SetLocked(true);
1432   }
1433   
1434   // Save state
1435   saveParaviewState(fileName.toLatin1().constData());
1436   myTemporaryFiles.append(fileName);
1437   
1438   // Increment the counter
1439   myStateCounter++;
1440
1441   updateObjBrowser();
1442 }
1443
1444 /*!
1445   \brief Restore the selected state by merging with the current one.
1446 */
1447 void PVGUI_Module::onAddState()
1448 {
1449   loadSelectedState(false);
1450 }
1451
1452 /*!
1453   \brief Clean the current state and restore the selected one.
1454 */
1455 void PVGUI_Module::onCleanAddState()
1456 {
1457   loadSelectedState(true);
1458 }
1459
1460 /*!
1461   \brief Rename the selected object.
1462 */
1463 void PVGUI_Module::onRename()
1464 {
1465   LightApp_SelectionMgr* aSelectionMgr = getApp()->selectionMgr();
1466   SALOME_ListIO aListIO;
1467   aSelectionMgr->selectedObjects(aListIO);
1468   
1469   if (aListIO.Extent() == 1 && aListIO.First()->hasEntry()) {
1470     std::string entry = aListIO.First()->getEntry();
1471     
1472     // Get SALOMEDS client study 
1473     _PTR(Study) studyDS = PARAVIS::GetCStudy(this);
1474     if(!studyDS) {
1475       return;
1476     }
1477     
1478     // Unlock the study if it is locked
1479     bool isLocked = studyDS->GetProperties()->IsLocked();
1480     if (isLocked) {
1481       studyDS->GetProperties()->SetLocked(false);
1482     }
1483     
1484     // Rename the selected state object
1485     _PTR(SObject) stateSObj = studyDS->FindObjectID(entry);
1486     if (!stateSObj) {
1487       return;
1488     }
1489     
1490     _PTR(GenericAttribute) anAttr;
1491     if (stateSObj->FindAttribute(anAttr, "AttributeName")) {
1492       _PTR(AttributeName) nameAttr (anAttr);
1493       QString newName = 
1494         LightApp_NameDlg::getName(getApp()->desktop(), nameAttr->Value().c_str());
1495       if (!newName.isEmpty()) {
1496         nameAttr->SetValue(newName.toLatin1().constData());
1497         aListIO.First()->setName(newName.toLatin1().constData());
1498       }
1499     }
1500     
1501     // Lock the study back if necessary
1502     if (isLocked) {
1503       studyDS->GetProperties()->SetLocked(true);
1504     }
1505     
1506     // Update object browser
1507     updateObjBrowser();
1508     
1509   }
1510 }
1511
1512 /*!
1513   \brief Delete the selected objects.
1514 */
1515 void PVGUI_Module::onDelete()
1516 {
1517   LightApp_SelectionMgr* aSelectionMgr = getApp()->selectionMgr();
1518   SALOME_ListIO aListIO;
1519   aSelectionMgr->selectedObjects(aListIO);
1520   
1521   if (aListIO.Extent() == 1 && aListIO.First()->hasEntry()) {
1522     std::string entry = aListIO.First()->getEntry();
1523     
1524     // Get SALOMEDS client study 
1525     _PTR(Study) studyDS = PARAVIS::GetCStudy(this);
1526     if(!studyDS) {
1527       return;
1528     }
1529     
1530     // Unlock the study if it is locked
1531     bool isLocked = studyDS->GetProperties()->IsLocked();
1532     if (isLocked) {
1533       studyDS->GetProperties()->SetLocked(false);
1534     }
1535     
1536     // Remove the selected state from the study
1537     _PTR(StudyBuilder) studyBuilder = studyDS->NewBuilder();
1538     _PTR(SObject) stateSObj = studyDS->FindObjectID(entry);
1539     studyBuilder->RemoveObject(stateSObj);
1540     
1541     // Lock the study back if necessary
1542     if (isLocked) {
1543       studyDS->GetProperties()->SetLocked(true);
1544     }
1545     
1546     // Update object browser
1547     updateObjBrowser();
1548   }
1549 }
1550
1551 /*!
1552   \brief Discover help project files from the resources.
1553   \return name of the help file. 
1554 */
1555 QString PVGUI_Module::getHelpFileName() {
1556   QString aPVHome(getenv("PVHOME"));
1557   if (aPVHome.isNull()) {
1558     qWarning("Wariable PVHOME is not defined");
1559     return QString();
1560   }
1561   QChar aSep = QDir::separator();
1562   //PARAVIEW_VERSION from the vtkPVConfig.h file
1563   QString aFileName =  aPVHome + aSep + "share" + aSep + "doc" + aSep + "paraview-"+ PARAVIEW_VERSION + aSep + "paraview.qch";
1564   return aFileName;
1565 }
1566
1567
1568 /*!
1569   \brief Load selected paraview state
1570
1571   If toClear == true, the current state will be cleared
1572 */
1573 void PVGUI_Module::loadSelectedState(bool toClear)
1574 {
1575   QString fileName;
1576
1577   LightApp_SelectionMgr* aSelectionMgr = getApp()->selectionMgr();
1578   SALOME_ListIO aListIO;
1579   aSelectionMgr->selectedObjects(aListIO);
1580   
1581   if (aListIO.Extent() == 1 && aListIO.First()->hasEntry()) {
1582     std::string entry = aListIO.First()->getEntry();
1583     
1584     // Get SALOMEDS client study 
1585     _PTR(Study) studyDS = PARAVIS::GetCStudy(this);
1586     if(!studyDS) {
1587       return;
1588     }
1589
1590     // Check local id
1591     _PTR(SObject) stateSObj = studyDS->FindObjectID(entry);
1592     _PTR(GenericAttribute) anAttr;
1593     if (!stateSObj->FindAttribute(anAttr, "AttributeLocalID")) {
1594       return;
1595     }
1596     _PTR(AttributeLocalID) anID(anAttr);
1597     if (!anID->Value() == PVSTATEID) {
1598       return;
1599     }
1600
1601     // Get state file name
1602     if (stateSObj->FindAttribute(anAttr, "AttributeString")) {
1603       _PTR(AttributeString) aStringAttr(anAttr);
1604       QString stringValue(aStringAttr->Value().c_str());
1605
1606       if (QFile::exists(stringValue)) {
1607         fileName = stringValue;
1608       }
1609     }
1610   }
1611   
1612   if (!fileName.isEmpty()) {
1613     if (toClear) {
1614       clearParaviewState();
1615     }
1616
1617     loadParaviewState(fileName.toLatin1().constData());
1618   } 
1619   else {
1620     SUIT_MessageBox::critical(getApp()->desktop(),
1621                               tr("ERR_ERROR"),
1622                               tr("ERR_STATE_CANNOT_BE_RESTORED"));
1623   }
1624 }
1625
1626 void PVGUI_Module::onRepresentationChanged(pqRepresentation*) {
1627
1628
1629   //rnv: to fix the issue "21712: [CEA 581] Preference to display legend by default"
1630   //     find the pqDisplayColorWidget instances and connect the variableChanged SIGNAL on the 
1631   //     onVariableChanged slot of this class. This connection needs to change visibility 
1632   //     of the "Colored Legend" after change the "Color By" array.
1633   QList<pqDisplayColorWidget*> aWidget = getApp()->desktop()->findChildren<pqDisplayColorWidget*>();
1634   
1635   for (int i = 0; i < aWidget.size() ; i++ ) {
1636     if( aWidget[i] ) {
1637       connect( aWidget[i], SIGNAL ( variableChanged ( pqVariableType, const QString ) ), 
1638                this, SLOT(onVariableChanged( pqVariableType, const QString) ), Qt::UniqueConnection );
1639     }    
1640   }
1641 }
1642
1643
1644 /*!
1645   \fn CAM_Module* createModule();
1646   \brief Export module instance (factory function).
1647   \return new created instance of the module
1648 */
1649
1650 #ifdef WNT
1651 #define PVGUI_EXPORT __declspec(dllexport)
1652 #else   // WNT
1653 #define PVGUI_EXPORT
1654 #endif  // WNT
1655
1656 extern "C" {
1657
1658   bool flag = false;
1659   PVGUI_EXPORT CAM_Module* createModule() {
1660     if(!flag) {
1661         vtkEDFHelperInit();
1662         flag = true;
1663     }      
1664     return new PVGUI_Module();
1665   }
1666   
1667   PVGUI_EXPORT char* getModuleVersion() {
1668     return (char*)PARAVIS_VERSION_STR;
1669   }
1670           
1671 }