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