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