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