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