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