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