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