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