]> SALOME platform Git repositories - modules/paravis.git/blob - src/PVGUI/PVGUI_Module.cxx
Salome HOME
Merge from BR_PARAVIS_LOT1_2 24/02/2010
[modules/paravis.git] / src / PVGUI / PVGUI_Module.cxx
1 // PARAVIS : ParaView wrapper SALOME module
2 //
3 // Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 // File   : PVGUI_Module.cxx
23 // Author : Julia DOROVSKIKH
24 //
25
26 #include <vtkPython.h> // Python first
27 #include "PVGUI_Module.h"
28
29 #include "SALOMEconfig.h"
30 #include CORBA_CLIENT_HEADER(VISU_Gen)
31 #include CORBA_SERVER_HEADER(SALOMEDS)
32
33
34 #include "PARAVIS_Gen_i.hh"
35
36 #include "PVGUI_Module_impl.h"
37 #include "PVGUI_ViewModel.h"
38 #include "PVGUI_ViewManager.h"
39 #include "PVGUI_ViewWindow.h"
40 #include "PVGUI_Tools.h"
41 //#include "PVGUI_Trace.h"
42
43 #include <SUIT_Desktop.h>
44 #include <SUIT_MessageBox.h>
45 #include <SUIT_ResourceMgr.h>
46 #include <SUIT_Session.h>
47 #include <SUIT_OverrideCursor.h>
48
49 // SALOME Includes
50 #include "SALOME_LifeCycleCORBA.hxx"
51 #include "SALOME_ListIteratorOfListIO.hxx"
52 #include "SALOMEDS_SObject.hxx"
53
54 #include <LightApp_SelectionMgr.h>
55 #include <SalomeApp_Application.h>
56 #include <SalomeApp_Study.h>
57 #include <SALOME_ListIO.hxx>
58 #include <SALOMEDS_Tool.hxx>
59 #include <PyInterp_Dispatcher.h>
60
61 #include <QtxActionMenuMgr.h>
62 #include <QtxActionToolMgr.h>
63
64 #include <QAction>
65 #include <QApplication>
66 #include <QCursor>
67 #include <QDir>
68 #include <QFile>
69 #include <QFileInfo>
70 #include <QIcon>
71 #include <QInputDialog>
72 #include <QStatusBar>
73 #include <QString>
74 #include <QStringList>
75 #include <QTimer>
76 #include <QToolBar>
77 #include <QTextStream>
78 #include <QShortcut>
79
80 #include <pqApplicationCore.h>
81 #include <pqActiveView.h>
82 #include <pqObjectBuilder.h>
83 #include <pqOptions.h>
84 #include <pqRenderView.h>
85 #include <pqServer.h>
86 #include <pqUndoStack.h>
87 #include <pqVCRController.h>
88 #include <pqViewManager.h>
89 #include <pqPipelineSource.h>
90 #include <vtkPVMain.h>
91 #include <vtkProcessModule.h>
92 #include <pqParaViewBehaviors.h>
93 #include <pqHelpReaction.h>
94 #include <vtkOutputWindow.h>
95 #include <pqPluginManager.h>
96 #include <vtkPVPluginInformation.h>
97 #include <pqSettings.h>
98 #include <pqPythonDialog.h>
99 #include <pqPythonManager.h>
100 #include <pqPythonShell.h>
101 #include "pqBrandPluginsLoader.h"
102 #include <pqLoadDataReaction.h>
103
104 /*
105  * Make sure all the kits register their classes with vtkInstantiator.
106  * Since ParaView uses Tcl wrapping, all of VTK is already compiled in
107  * anyway.  The instantiators will add no more code for the linker to
108  * collect.
109  */
110
111 #include <vtkCommonInstantiator.h>
112 #include <vtkFilteringInstantiator.h>
113 #include <vtkGenericFilteringInstantiator.h>
114 #include <vtkIOInstantiator.h>
115 #include <vtkImagingInstantiator.h>
116 #include <vtkInfovisInstantiator.h>
117 #include <vtkGraphicsInstantiator.h>
118
119 #include <vtkRenderingInstantiator.h>
120 #include <vtkVolumeRenderingInstantiator.h>
121 #include <vtkHybridInstantiator.h>
122 #include <vtkParallelInstantiator.h>
123
124 #include <pqAlwaysConnectedBehavior.h>
125 #include <pqApplicationCore.h>
126 #include <pqAutoLoadPluginXMLBehavior.h>
127 #include <pqCommandLineOptionsBehavior.h>
128 #include <pqCrashRecoveryBehavior.h>
129 #include <pqDataTimeStepBehavior.h>
130 #include <pqDefaultViewBehavior.h>
131 #include <pqDeleteBehavior.h>
132 #include <pqPersistentMainWindowStateBehavior.h>
133 #include <pqPluginActionGroupBehavior.h>
134 #include <pqPluginDockWidgetsBehavior.h>
135 #include <pqPluginManager.h>
136 #include <pqPVNewSourceBehavior.h>
137 //#include <pqQtMessageHandlerBehavior.h>
138 #include <pqSpreadSheetVisibilityBehavior.h>
139 #include <pqStandardViewModules.h>
140 #include <pqUndoRedoBehavior.h>
141 #include <pqViewFrameActionsBehavior.h>
142
143
144 //----------------------------------------------------------------------------
145 pqApplicationCore* PVGUI_Module::pqImplementation::Core = 0;
146 PVGUI_OutputWindowAdapter* PVGUI_Module::pqImplementation::OutputWindowAdapter = 0;
147 QPointer<pqHelpWindow> PVGUI_Module::pqImplementation::helpWindow = 0;
148
149 PVGUI_Module* ParavisModule = 0;
150
151 /*!
152   \mainpage
153
154   <h2>Building and installing PARAVIS</h2>
155   As any other SALOME module, PARAVIS requires PARAVIS_ROOT_DIR environment variable to be set to PARAVIS
156   installation directory.
157   Other variables needed for correct detection of ParaView location:
158   \li PVHOME - points at the ParaView installation directory tree
159   \li PVVERSION - number of ParaView version
160
161   It also requires common SALOME environment including GUI_ROOT_DIR and other prerequsites.
162
163
164   PARAVIS module can be launched using the following commands:
165   \li Full SALOME configuration
166   \code
167   runSalome --modules="PARAVIS"
168   \endcode
169
170   <h2>ParaView GUI integration</h2>
171   <h3>ParaView GUI integration overview</h3>
172
173   The main idea is to reuse ParaView GUI internal logic as much as possible, providing a layer 
174   between it and SALOME GUI that hides the following SALOME GUI implementation details from ParaView:
175
176   \li SALOME GUI executable and Qt event loop
177   \li SALOME GUI desktop
178   \li Dock windows areas
179   \li SALOME menu and toolbar managers
180
181   Major part of the integration is implemented in PVGUI_Module class.
182
183   <h3>ParaView client initalization</h3>
184
185   ParaView client initalization is performed when an instance of PVGUI_Module class has been created 
186   and \link PVGUI_Module::initialize() PVGUI_Module::initialize()\endlink method is called by SALOME GUI.
187   The actual client start-up is done in \link PVGUI_Module::pvInit() PVGUI_Module::pvInit()\endlink method. 
188   
189
190   <h3>Multi-view manager</h3>
191
192   SALOME GUI requires that each kind of view be implemnted with help of (at least) three classes. For ParaView multi-view manager 
193   these are:
194
195   \li PVGUI_ViewManager - view manager class
196   \li PVGUI_Viewer      - view model class
197   \li PVGUI_ViewWindow  - view window class that acts as a parent for %pqViewManager
198
199   Single instances of PVGUI_ViewManager and PVGUI_ViewWindow classes are created by \link PVGUI_Module::showView() 
200   PVGUI_Module::showView()\endlink method upon the first PARAVIS module activation. The same method hides the multi-view manager 
201   when the module is deactivated (the user switches to another module or a study is closed). 
202   A special trick is used to make PVGUI_ViewWindow the parent of %pqViewManager widget. It is created initally by %pqMainWindowCore
203   with the desktop as a parent, so when it is shown PVGUI_ViewWindow instance is passed to its setParent() method. In  
204   \link PVGUI_ViewWindow::~PVGUI_ViewWindow() PVGUI_ViewWindow::~PVGUI_ViewWindow()\endlink the parent is nullified to avoid deletion
205   of %pqViewManager widget that would break %pqMainWindowCore class.
206
207   <h3>ParaView plugins</h3>
208   ParaView server and client plugins are managed by %pqMainWindowCore slots that has full access to PARAVIS menus and toolbars. 
209   As a result they appears automatically in PARAVIS menus and toolbars if loaded successfully.
210 */
211
212 /*!
213   \class PVGUI_Module
214   \brief Implementation 
215          SALOME module wrapping ParaView GUI.
216 */
217
218 /*!
219   \brief Constructor. Sets the default name for the module.
220 */
221 PVGUI_Module::PVGUI_Module()
222   : SalomeApp_Module( "PARAVIS" ),
223     LightApp_Module( "PARAVIS" ),
224     Implementation( 0 ),
225     mySelectionControlsTb( -1 ),
226     mySourcesMenuId( -1 ),
227     myFiltersMenuId( -1 ),
228     myMacrosMenuId(-1),
229     myToolbarsMenuId(-1),
230     myOldMsgHandler(0)
231 {
232   ParavisModule = this;
233 }
234
235 /*!
236   \brief Destructor.
237 */
238 PVGUI_Module::~PVGUI_Module()
239 {
240 }
241
242
243
244 /*!
245   \brief Initialize module. Creates menus, prepares context menu, etc.
246   \param app SALOME GUI application instance
247 */
248 void PVGUI_Module::initialize( CAM_Application* app )
249 {
250   SalomeApp_Module::initialize( app );
251
252   // Uncomment to debug ParaView initialization
253   // "aa" used instead of "i" as GDB doesn't like "i" variables :)
254   /*
255   int aa = 1;
256   while( aa ){
257     aa = aa;
258   }
259   */
260   
261   // Initialize ParaView client
262   pvInit();
263
264   // Create GUI elements (menus, toolbars, dock widgets)
265   if ( !Implementation ){
266     SalomeApp_Application* anApp = getApp();
267
268     // Simulate ParaView client main window
269     Implementation = new pqImplementation( anApp->desktop() );
270
271     setupDockWidgets();
272     
273     pvCreateActions();
274     pvCreateToolBars();
275     pvCreateMenus();
276
277     // new pqParaViewBehaviors(anApp->desktop(), this);
278     // Has to be replaced in order to exclude using of pqQtMessageHandlerBehaviour
279     //  Start pqParaViewBehaviors
280     // Register ParaView interfaces.
281     pqPluginManager* pgm = pqApplicationCore::instance()->getPluginManager();
282
283     // * adds support for standard paraview views.
284     pgm->addInterface(new pqStandardViewModules(pgm));
285
286     // Load plugins distributed with application.
287     pqApplicationCore::instance()->loadDistributedPlugins();
288
289     // Define application behaviors.
290     //new pqQtMessageHandlerBehavior(this);
291     new pqDataTimeStepBehavior(this);
292     new pqViewFrameActionsBehavior(this);
293     new pqSpreadSheetVisibilityBehavior(this);
294     new pqDefaultViewBehavior(this);
295     new pqAlwaysConnectedBehavior(this);
296     new pqPVNewSourceBehavior(this);
297     new pqDeleteBehavior(this);
298     new pqUndoRedoBehavior(this);
299     new pqCrashRecoveryBehavior(this);
300     new pqAutoLoadPluginXMLBehavior(this);
301     new pqPluginDockWidgetsBehavior(getApp()->desktop());
302     new pqPluginActionGroupBehavior(getApp()->desktop());
303     new pqCommandLineOptionsBehavior(this);
304     new pqPersistentMainWindowStateBehavior(getApp()->desktop());
305
306     // Setup quick-launch shortcuts.
307     QShortcut *ctrlSpace = new QShortcut(Qt::CTRL + Qt::Key_Space,
308       getApp()->desktop());
309     QObject::connect(ctrlSpace, SIGNAL(activated()),
310       pqApplicationCore::instance(), SLOT(quickLaunch()));
311     QShortcut *altSpace = new QShortcut(Qt::ALT + Qt::Key_Space,
312       getApp()->desktop());
313     QObject::connect(altSpace, SIGNAL(activated()),
314       pqApplicationCore::instance(), SLOT(quickLaunch()));
315     //  End pqParaViewBehaviors
316     
317
318     SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
319     QString aPath = resMgr->stringValue("resources", "PARAVIS", QString());
320     if (!aPath.isNull()) {
321       pqImplementation::Core->loadConfiguration(aPath + QDir::separator() + "ParaViewFilters.xml");
322       pqImplementation::Core->loadConfiguration(aPath + QDir::separator() + "ParaViewReaders.xml");
323       pqImplementation::Core->loadConfiguration(aPath + QDir::separator() + "ParaViewSources.xml");
324       pqImplementation::Core->loadConfiguration(aPath + QDir::separator() + "ParaViewWriters.xml");
325     }
326     // Now that we're ready, initialize everything ...
327
328
329     // Force creation of engine
330     PARAVIS::GetParavisGen(this);
331     updateObjBrowser();
332   }
333
334   // Initialize list of toolbars
335   QCoreApplication::processEvents();
336   QList<QToolBar*> aBars = getParaViewToolbars();
337   foreach (QToolBar* aBar, aBars) {
338     myToolbarState[aBar] = true;
339   }
340
341   SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr();
342   bool isStop = aResourceMgr->booleanValue( "PARAVIS", "stop_trace", false );
343   if(!isStop) 
344     QTimer::singleShot(50, this, SLOT(activateTrace()));
345 }
346
347
348 void PVGUI_Module::activateTrace()
349 {
350   PyInterp_Dispatcher* aDispatcher = PyInterp_Dispatcher::Get();
351   if (aDispatcher->IsBusy()) {
352     QTimer::singleShot(50, this, SLOT(activateTrace()));
353     return;
354   }
355
356   pqPythonDialog* pyDiag = 0;
357   pqPythonManager* manager = qobject_cast<pqPythonManager*>(
358                              pqApplicationCore::instance()->manager("PYTHON_MANAGER"));
359   if (manager)  {
360     pyDiag = manager->pythonShellDialog();
361   }
362   if (pyDiag) {
363     pyDiag->runString("try:\n"
364                       "  from paraview import smtrace\n"
365                       "  smtrace.start_trace()\n"
366                       "  print 'Trace started.'\n"
367                       "except: raise RuntimeError('could not import paraview.smtrace')\n");
368   }
369 }
370
371
372
373 /*!
374   \brief Get list of compliant dockable GUI elements
375   \param m map to be filled in ("type":"default_position")
376 */
377 void PVGUI_Module::windows( QMap<int, int>& m ) const
378 {
379   m.insert( LightApp_Application::WT_ObjectBrowser, Qt::LeftDockWidgetArea );
380   m.insert( LightApp_Application::WT_PyConsole, Qt::BottomDockWidgetArea );
381   // ParaView diagnostic output redirected here
382   m.insert( LightApp_Application::WT_LogWindow, Qt::BottomDockWidgetArea );
383 }
384
385 /*!
386   \brief Static method, performs initialization of ParaView session.
387   \return \c true if ParaView has been initialized successfully, otherwise false
388 */
389 bool PVGUI_Module::pvInit()
390 {
391   if ( !pqImplementation::Core ){
392     // Obtain command-line arguments
393     int argc = 0;
394     QStringList args = QApplication::arguments();
395     char** argv = new char*[args.size()];
396     for ( QStringList::const_iterator it = args.begin(); argc < 1 && it != args.end(); it++, argc++ ) {
397       argv[argc] = strdup( (*it).toLatin1().constData() );
398     }
399     pqImplementation::Core = new pqPVApplicationCore (argc, argv);
400     if (pqImplementation::Core->getOptions()->GetHelpSelected() ||
401         pqImplementation::Core->getOptions()->GetUnknownArgument() ||
402         pqImplementation::Core->getOptions()->GetErrorMessage() ||
403         pqImplementation::Core->getOptions()->GetTellVersion()) {
404       return false;
405     }
406     // VSV: Code from Initializer - it seems that it does nothing
407
408     // Not sure why this is needed. Andy added this ages ago with comment saying
409     // needed for Mac apps. Need to check that it's indeed still required.
410     QDir dir(QApplication::applicationDirPath());
411     dir.cdUp();
412     dir.cd("Plugins");
413     QApplication::addLibraryPath(dir.absolutePath());
414     // Load required application plugins.
415     QString plugin_string = "";
416     QStringList plugin_list = plugin_string.split(';',QString::SkipEmptyParts);
417     pqBrandPluginsLoader loader;
418     if (loader.loadPlugins(plugin_list) == false) {
419       printf("Failed to load required plugins for this application\n");
420       return false;
421     }
422
423     // Load optional plugins.
424     plugin_string = "";
425     plugin_list = plugin_string.split(';',QString::SkipEmptyParts);
426     loader.loadPlugins(plugin_list, true); //quietly skip not-found plugins.
427
428     // End of Initializer code
429
430     //qInstallMsgHandler(0); // switch off standard Paraview message handler
431     pqImplementation::OutputWindowAdapter = PVGUI_OutputWindowAdapter::New();
432     vtkOutputWindow::SetInstance(pqImplementation::OutputWindowAdapter);
433
434     //pqPluginManager* pgm = pqApplicationCore::instance()->getPluginManager();
435     //pgm->loadExtensions(NULL);
436
437     new pqViewManager(); // it registers as "MULTIVIEW_MANAGER on creation
438     
439     if (argc == 1)
440       free(argv[0]); // because in creation argc < 1
441     delete[] argv;
442   }
443   
444   return true;
445 }
446  
447 /*!
448   \brief Shows (toShow = true) or hides ParaView view window
449 */
450 void PVGUI_Module::showView( bool toShow )
451 {
452   SalomeApp_Application* anApp = getApp();
453   PVGUI_ViewManager* viewMgr =
454     dynamic_cast<PVGUI_ViewManager*>( anApp->getViewManager( PVGUI_Viewer::Type(), false ) );
455   if ( !viewMgr ) {
456     viewMgr = new PVGUI_ViewManager( anApp->activeStudy(), anApp->desktop() );
457     anApp->addViewManager( viewMgr );
458     connect( viewMgr, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
459              anApp, SLOT( onCloseView( SUIT_ViewManager* ) ) );
460   }
461
462   PVGUI_ViewWindow* pvWnd = dynamic_cast<PVGUI_ViewWindow*>( viewMgr->getActiveView() );
463   if ( !pvWnd ) {
464     pvWnd = dynamic_cast<PVGUI_ViewWindow*>( viewMgr->createViewWindow() );
465   }
466
467   pvWnd->setShown( toShow );
468 }
469
470
471 // void PVGUI_Module::connectToPlay()
472 // {
473 //   connect( action(PlayId), SIGNAL( triggered() ), &Implementation->Core.VCRController(), SLOT( onPlay() ) );
474 // }
475
476
477 /*!
478   \brief Slot to show help for proxy.
479 */
480 void PVGUI_Module::showHelpForProxy( const QString& proxy )
481 {
482   //pqHelpReaction::showHelp(QString("qthelp://paraview.org/paraview/%1.html").arg(proxy));
483   showHelp(QString("qthelp://paraview.org/paraview/%1.html").arg(proxy));
484 }
485
486 void PVGUI_Module::showParaViewHelp()
487 {
488   showHelp(QString());
489 }
490
491 void PVGUI_Module::showHelp(const QString& url)
492 {
493   if (pqImplementation::helpWindow) {
494    // raise assistant window;
495     pqImplementation::helpWindow->show();
496     pqImplementation::helpWindow->raise();
497     if (!url.isEmpty()) {
498       pqImplementation::helpWindow->showPage(url);
499     }
500     return;
501   }
502
503  // * Discover help project files from the resources.
504   QString aPVHome(getenv("PVHOME"));
505   if (aPVHome.isNull()) {
506     qWarning("Wariable PVHOME is not defined");
507     return;
508   }
509   QChar aSep = QDir::separator();
510   QString aFile =  aPVHome + aSep + "doc" + aSep + "paraview.qch";
511
512   if (!QFile::exists(aFile)) {
513     qWarning("Help file do not found");
514     return;
515   }
516   
517   pqImplementation::helpWindow = new pqHelpWindow(QString("ParaView Online Help"), getApp()->desktop());
518   QString namespace_name = pqImplementation::helpWindow->registerDocumentation(aFile);
519
520   pqImplementation::helpWindow->showHomePage(namespace_name);
521   pqImplementation::helpWindow->show();
522   pqImplementation::helpWindow->raise();
523   if (!url.isEmpty()) {
524     pqImplementation::helpWindow->showPage(url);
525   }
526 }
527
528
529
530 /*!
531   \brief Slot to show the waiting state.
532 */
533 void PVGUI_Module::onPreAccept()
534 {
535   getApp()->desktop()->statusBar()->showMessage(tr("STB_PREACCEPT"));
536   QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
537 }
538
539 /*!
540   \brief Slot to show the ready state.
541 */
542 void PVGUI_Module::onPostAccept()
543 {
544   getApp()->desktop()->statusBar()->showMessage(tr("STB_POSTACCEPT"), 2000);
545   QTimer::singleShot(0, this, SLOT(endWaitCursor()));
546 }
547
548 /*!
549   \brief Slot to switch off wait cursor.
550 */
551 void PVGUI_Module::endWaitCursor()
552 {
553   QApplication::restoreOverrideCursor();
554 }
555
556 /*!
557   \brief Returns the ParaView multi-view manager.
558 */
559 pqViewManager* PVGUI_Module::getMultiViewManager() const
560 {
561   return qobject_cast<pqViewManager*>(pqApplicationCore::instance()->manager("MULTIVIEW_MANAGER"));
562 }
563
564
565 static void ParavisMessageOutput(QtMsgType type, const char *msg)
566 {
567   switch(type)
568     {
569   case QtDebugMsg:
570     vtkOutputWindow::GetInstance()->DisplayText(msg);
571     break;
572   case QtWarningMsg:
573     vtkOutputWindow::GetInstance()->DisplayErrorText(msg);
574     break;
575   case QtCriticalMsg:
576     vtkOutputWindow::GetInstance()->DisplayErrorText(msg);
577     break;
578   case QtFatalMsg:
579     vtkOutputWindow::GetInstance()->DisplayErrorText(msg);
580     break;
581     }
582 }
583
584
585
586 /*!
587   \brief Activate module.
588   \param study current study
589   \return \c true if activaion is done successfully or 0 to prevent
590   activation on error
591 */
592 bool PVGUI_Module::activateModule( SUIT_Study* study )
593 {
594   myOldMsgHandler = qInstallMsgHandler(ParavisMessageOutput);
595
596   bool isDone = SalomeApp_Module::activateModule( study );
597   if ( !isDone ) return false;
598
599   showView( true );
600   if ( mySourcesMenuId != -1 ) menuMgr()->show(mySourcesMenuId);
601   if ( myFiltersMenuId != -1 ) menuMgr()->show(myFiltersMenuId);
602   if ( myFiltersMenuId != -1 ) menuMgr()->show(myMacrosMenuId);
603   if ( myFiltersMenuId != -1 ) menuMgr()->show(myToolbarsMenuId);
604   setMenuShown( true );
605   setToolShown( true );
606
607   if (myToolbarState.size() > 0) {
608     SUIT_Desktop* desk = application()->desktop();
609     QList<QToolBar*> aToolbars = myToolbarState.keys();
610     foreach(QToolBar* aBar, aToolbars) {
611       aBar->setParent(desk);
612       aBar->setVisible(myToolbarState[aBar]);
613     }
614   }
615
616   restoreDockWidgetsState();
617
618   return isDone;
619 }
620
621
622 /*!
623   \brief Deactivate module.
624   \param study current study
625   \return \c true if deactivaion is done successfully or 0 to prevent
626   deactivation on error
627 */
628 bool PVGUI_Module::deactivateModule( SUIT_Study* study )
629 {
630   if (pqImplementation::helpWindow) {
631     pqImplementation::helpWindow->hide();
632   }
633   showView( false );
634
635   // hide menus
636   menuMgr()->hide(mySourcesMenuId);
637   menuMgr()->hide(myFiltersMenuId);
638   menuMgr()->hide(myMacrosMenuId);
639   menuMgr()->hide(myToolbarsMenuId);
640   setMenuShown( false );
641   setToolShown( false );
642
643   saveDockWidgetsState();
644
645   // hide toolbars
646   QList<QToolBar*> aToolbars = myToolbarState.keys();
647   foreach(QToolBar* aBar, aToolbars) {
648     myToolbarState[aBar] = aBar->isVisible();
649     aBar->hide();
650     aBar->setParent(0);
651   }
652
653   if (myOldMsgHandler)
654     qInstallMsgHandler(myOldMsgHandler);
655   return SalomeApp_Module::deactivateModule( study );
656 }
657
658
659 /*!
660   \brief Called when application is closed.
661
662   Process finalize application functionality from ParaView in order to save server settings
663   and nullify application pointer if the application is being closed.
664
665   \param theApp application
666 */
667 void PVGUI_Module::onApplicationClosed( SUIT_Application* theApp )
668 {
669   pqApplicationCore::instance()->settings()->sync();
670   int aAppsNb = SUIT_Session::session()->applications().size();
671   if (aAppsNb == 1) {
672     deleteTemporaryFiles();
673     //pvShutdown();
674   }
675   CAM_Module::onApplicationClosed(theApp);
676 }
677
678 /*!
679   \brief Compares the contents of the window with the given reference image,
680   returns true if they "match" within some tolerance.
681 */
682 /*VSV it seems that this method is obsolete
683 bool PVGUI_Module::compareView( const QString& ReferenceImage, double Threshold,
684                                 std::ostream& Output, const QString& TempDirectory )
685 {
686   if ( Implementation )
687     return Implementation->Core.compareView( ReferenceImage, Threshold, Output, TempDirectory );
688   return false;
689 }
690 */
691 QString PVGUI_Module::engineIOR() const
692 {
693   CORBA::String_var anIOR = PARAVIS::GetParavisGen(this)->GetIOR();
694   return QString(anIOR.in());
695 }
696
697
698 /*!
699   \brief Open file of format supported by ParaView
700 */
701 void PVGUI_Module::openFile(const char* theName)
702 {
703   QStringList aFiles;
704   aFiles<<theName;
705   pqLoadDataReaction::loadData(aFiles);
706 }
707
708 /*!
709   \brief Returns trace string
710 */
711 QString PVGUI_Module::getTraceString()
712 {
713   pqPythonDialog* pyDiag = 0;
714   pqPythonManager* manager = qobject_cast<pqPythonManager*>(
715                              pqApplicationCore::instance()->manager("PYTHON_MANAGER"));
716   if (manager)  {
717     pyDiag = manager->pythonShellDialog();
718   }
719
720   QString traceString;
721   if (pyDiag) {
722     pyDiag->runString("try:\n"
723                       "  from paraview import smtrace\n"
724                       "  __smtraceString = smtrace.get_trace_string()\n"
725                       "except:\n"
726                       "  __smtraceString = str()\n"
727                       "  raise RuntimeError('could not import paraview.smtrace')\n");
728     pyDiag->shell()->makeCurrent();
729     PyObject* main_module = PyImport_AddModule((char*)"__main__");
730     PyObject* global_dict = PyModule_GetDict(main_module);
731     PyObject* string_object = PyDict_GetItemString(global_dict, "__smtraceString");
732     char* string_ptr = PyString_AsString(string_object);
733     if (string_ptr) {
734       traceString = string_ptr;
735     }
736     pyDiag->shell()->releaseControl();
737   }
738   return traceString;
739 }
740
741 /*!
742   \brief Saves trace string to disk file
743 */
744 void PVGUI_Module::saveTrace(const char* theName)
745 {
746   //save_trace(theName);
747   QFile file(theName);
748   if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
749     MESSAGE( "Could not open file:" << theName );
750     return;
751   }
752   QTextStream out(&file);
753   out << getTraceString();
754   file.close();
755 }
756
757 /*!
758   \brief Saves ParaView state to a disk file
759 */
760 void PVGUI_Module::saveParaviewState(const char* theFileName)
761 {
762   Implementation->Core->saveState(theFileName);
763 }
764
765 /*!
766   \brief Restores ParaView state from a disk file
767 */
768 void PVGUI_Module::loadParaviewState(const char* theFileName)
769 {
770   Implementation->Core->loadState(theFileName, getActiveServer());
771 }
772
773 /*!
774   \brief Imports MED data from VISU module by data entry
775 */
776 void PVGUI_Module::onImportFromVisu(QString theEntry)
777 {
778 #ifdef WITH_VISU
779   SUIT_OverrideCursor aWaitCursor;
780
781   // get active study
782   SalomeApp_Study* activeStudy = dynamic_cast<SalomeApp_Study*>(application()->activeStudy());
783   if(!activeStudy) return;
784
785   // get SALOMEDS client study 
786   _PTR(Study) aStudy = activeStudy->studyDS();
787   if(!aStudy) return;
788
789   // find VISU component in a study
790   _PTR(SComponent) aVisuComp = aStudy->FindComponent( "VISU" );
791   if(!aVisuComp) return;
792
793   // get SObject client by entry
794   _PTR(SObject) aSObj = aStudy->FindObjectID(qPrintable(theEntry));
795   if (!aSObj) return;
796
797   // get CORBA SObject
798   SALOMEDS_SObject* aSObject = _CAST(SObject, aSObj);
799   if ( !aSObject ) return;
800
801   // load VISU engine
802   SALOME_NamingService* aNamingService = SalomeApp_Application::namingService();
803   SALOME_LifeCycleCORBA aLCC(aNamingService);
804
805   Engines::Component_var aComponent = aLCC.FindOrLoad_Component("FactoryServer","VISU");
806   VISU::VISU_Gen_var aVISU = VISU::VISU_Gen::_narrow(aComponent);
807   if(CORBA::is_nil(aVISU)) return;
808
809   _PTR(StudyBuilder) aStudyBuilder = aStudy->NewBuilder();
810   aStudyBuilder->LoadWith( aVisuComp, SalomeApp_Application::orb()->object_to_string(aVISU) );
811
812   // set current study to VISU engine
813   //aVISU->SetCurrentStudy(aStudyVar);
814
815   // get VISU result object
816   CORBA::Object_var aResultObject = aSObject->GetObject();
817   if (CORBA::is_nil(aResultObject)) return;
818   VISU::Result_var aResult = VISU::Result::_narrow( aResultObject );
819   if (CORBA::is_nil(aResult)) return;
820
821   // export VISU result to the MED file
822   std::string aTmpDir = SALOMEDS_Tool::GetTmpDir();
823   std::string aFileName = aSObject->GetName();
824   std::string aFilePath = aTmpDir + aFileName;
825
826   if (aResult->ExportMED(aFilePath.c_str())) {
827     openFile(aFilePath.c_str());
828     myTemporaryFiles.append(QString(aFilePath.c_str()));
829   }
830 #else
831   MESSAGE("Visu module is not found.");
832 #endif
833 }
834
835 /*!
836   \brief Deletes temporary files created during import operation from VISU
837 */
838 void PVGUI_Module::deleteTemporaryFiles()
839 {
840   foreach(QString aFile, myTemporaryFiles) {
841     if (QFile::exists(aFile)) {
842       QFile::remove(aFile);
843     }
844   }
845 }
846
847
848 /*!
849   \brief Returns current active ParaView server
850 */
851 pqServer* PVGUI_Module::getActiveServer()
852 {
853   return Implementation->Core->getActiveServer();
854 }
855
856
857 /*!
858   \brief Creates PARAVIS preference pane 
859 */
860 void PVGUI_Module::createPreferences()
861 {
862   int TraceTab = addPreference( tr( "TIT_TRACE" ) );
863   addPreference( tr( "PREF_STOP_TRACE" ), TraceTab, LightApp_Preferences::Bool, "PARAVIS", "stop_trace");
864
865   int aSaveType = addPreference(tr( "PREF_SAVE_TYPE_LBL" ), TraceTab,
866                                 LightApp_Preferences::Selector,
867                                 "PARAVIS", "savestate_type");
868   QList<QVariant> aIndices;
869   QStringList aStrings;
870   aIndices<<0<<1<<2;
871   aStrings<<tr("PREF_SAVE_TYPE_0");
872   aStrings<<tr("PREF_SAVE_TYPE_1");
873   aStrings<<tr("PREF_SAVE_TYPE_2");
874   setPreferenceProperty(aSaveType, "strings", aStrings);
875   setPreferenceProperty(aSaveType, "indexes", aIndices);
876 }
877
878
879
880 /*!
881   \fn CAM_Module* createModule();
882   \brief Export module instance (factory function).
883   \return new created instance of the module
884 */
885
886 #ifdef WNT
887 #define PVGUI_EXPORT __declspec(dllexport)
888 #else   // WNT
889 #define PVGUI_EXPORT
890 #endif  // WNT
891
892 extern "C" {
893   PVGUI_EXPORT CAM_Module* createModule() {
894     return new PVGUI_Module();
895   }
896 }