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