1 // PARAVIS : ParaView wrapper SALOME module
3 // Copyright (C) 2010-2012 CEA/DEN, EDF R&D
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.
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.
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
19 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 // File : PVGUI_Module.cxx
22 // Author : Julia DOROVSKIKH
24 #include <Standard_math.hxx> // E.A. must be included before Python.h to fix compilation on windows
26 #undef HAVE_FINITE // VSR: avoid compilation warning on Linux : "HAVE_FINITE" redefined
28 #include <vtkPython.h> // Python first
29 #include "PVGUI_Module.h"
31 #include "SALOMEconfig.h"
33 #include CORBA_CLIENT_HEADER(VISU_Gen)
35 #include CORBA_SERVER_HEADER(SALOMEDS)
38 #include "PARAVIS_Gen_i.hh"
42 #include "PVGUI_ViewModel.h"
43 #include "PVGUI_ViewManager.h"
44 #include "PVGUI_ViewWindow.h"
45 #include "PVGUI_Tools.h"
46 #include "PVGUI_ParaViewSettingsPane.h"
47 #include "PVGUI_OutputWindowAdapter.h"
49 #include <SUIT_DataBrowser.h>
50 #include <SUIT_Desktop.h>
51 #include <SUIT_MessageBox.h>
52 #include <SUIT_ResourceMgr.h>
53 #include <SUIT_Session.h>
54 #include <SUIT_OverrideCursor.h>
57 #include "SALOME_LifeCycleCORBA.hxx"
58 #include "SALOMEDS_SObject.hxx"
60 #include "LightApp_SelectionMgr.h"
61 #include "LightApp_NameDlg.h"
63 #include <SalomeApp_Application.h>
64 #include <SalomeApp_Study.h>
65 #include <SALOME_ListIO.hxx>
66 #include <SALOMEDS_Tool.hxx>
67 #include <PyInterp_Dispatcher.h>
69 #include <QtxActionMenuMgr.h>
70 #include <QtxActionToolMgr.h>
73 #include <QApplication>
79 #include <QInputDialog>
83 #include <QStringList>
86 #include <QTextStream>
88 #include <QDockWidget>
89 #include <QHelpEngine>
91 #include <pqApplicationCore.h>
92 #include <pqPVApplicationCore.h>
93 #include <pqActiveView.h>
94 #include <pqObjectBuilder.h>
95 #include <pqOptions.h>
96 #include <pqRenderView.h>
98 #include <pqUndoStack.h>
99 #include <pqVCRController.h>
100 #include <pqTabbedMultiViewWidget.h>
101 #include <pqPipelineSource.h>
102 //#include <vtkPVMain.h>
103 #include <vtkProcessModule.h>
104 #include <pqParaViewBehaviors.h>
105 #include <pqHelpReaction.h>
106 #include <vtkOutputWindow.h>
107 #include <pqPluginManager.h>
108 //#include <vtkPVPluginInformation.h>
109 #include "pqInterfaceTracker.h"
110 #include <pqSettings.h>
111 #include <pqPythonDialog.h>
112 #include <pqPythonManager.h>
113 #include <pqPythonShell.h>
114 #include <pqBrandPluginsLoader.h>
115 #include <pqLoadDataReaction.h>
116 #include <vtkEventQtSlotConnect.h>
117 #include <pqPythonScriptEditor.h>
118 #include <pqStandardSummaryPanelImplementation.h>
119 #include <pqCollaborationBehavior.h>
121 #include <PARAVIS_version.h>
123 #include <vtkPVConfig.h>
126 * Make sure all the kits register their classes with vtkInstantiator.
127 * Since ParaView uses Tcl wrapping, all of VTK is already compiled in
128 * anyway. The instantiators will add no more code for the linker to
132 #include <vtkCommonInstantiator.h>
133 #include <vtkFilteringInstantiator.h>
134 #include <vtkGenericFilteringInstantiator.h>
135 #include <vtkIOInstantiator.h>
136 #include <vtkImagingInstantiator.h>
137 #include <vtkInfovisInstantiator.h>
138 #include <vtkGraphicsInstantiator.h>
140 #include <vtkRenderingInstantiator.h>
141 #include <vtkVolumeRenderingInstantiator.h>
142 #include <vtkHybridInstantiator.h>
143 #include <vtkParallelInstantiator.h>
145 #include <pqAlwaysConnectedBehavior.h>
146 #include <pqApplicationCore.h>
147 #include <pqAutoLoadPluginXMLBehavior.h>
148 #include <pqCommandLineOptionsBehavior.h>
149 #include <pqCrashRecoveryBehavior.h>
150 #include <pqDataTimeStepBehavior.h>
151 #include <pqDefaultViewBehavior.h>
152 #include <pqDeleteBehavior.h>
153 #include <pqObjectPickingBehavior.h>
154 #include <pqPersistentMainWindowStateBehavior.h>
155 #include <pqPipelineContextMenuBehavior.h>
156 #include <pqPluginActionGroupBehavior.h>
157 #include <pqPluginDockWidgetsBehavior.h>
158 #include <pqPluginManager.h>
159 #include <pqPVNewSourceBehavior.h>
160 #include <pqSpreadSheetVisibilityBehavior.h>
161 #include <pqStandardViewModules.h>
162 #include <pqUndoRedoBehavior.h>
163 #include <pqViewFrameActionsBehavior.h>
164 #include <pqServerManagerObserver.h>
167 //----------------------------------------------------------------------------
168 pqPVApplicationCore* PVGUI_Module::MyCoreApp = 0;
169 //PVGUI_OutputWindowAdapter* PVGUI_Module::pqImplementation::OutputWindowAdapter = 0;
170 //QPointer<pqHelpWindow> PVGUI_Module::pqImplementation::helpWindow = 0;
172 PVGUI_Module* ParavisModule = 0;
177 <h2>Building and installing PARAVIS</h2>
178 As any other SALOME module, PARAVIS requires PARAVIS_ROOT_DIR environment variable to be set to PARAVIS
179 installation directory.
180 Other variables needed for correct detection of ParaView location:
181 \li PVHOME - points at the ParaView installation directory tree
182 \li PVVERSION - number of ParaView version
184 It also requires common SALOME environment including GUI_ROOT_DIR and other prerequsites.
187 PARAVIS module can be launched using the following commands:
188 \li Full SALOME configuration
190 runSalome --modules="PARAVIS"
193 <h2>ParaView GUI integration</h2>
194 <h3>ParaView GUI integration overview</h3>
196 The main idea is to reuse ParaView GUI internal logic as much as possible, providing a layer
197 between it and SALOME GUI that hides the following SALOME GUI implementation details from ParaView:
199 \li SALOME GUI executable and Qt event loop
200 \li SALOME GUI desktop
201 \li Dock windows areas
202 \li SALOME menu and toolbar managers
204 Major part of the integration is implemented in PVGUI_Module class.
206 <h3>ParaView client initalization</h3>
208 ParaView client initalization is performed when an instance of PVGUI_Module class has been created
209 and \link PVGUI_Module::initialize() PVGUI_Module::initialize()\endlink method is called by SALOME GUI.
210 The actual client start-up is done in \link PVGUI_Module::pvInit() PVGUI_Module::pvInit()\endlink method.
213 <h3>Multi-view manager</h3>
215 SALOME GUI requires that each kind of view be implemnted with help of (at least) three classes. For ParaView multi-view manager
218 \li PVGUI_ViewManager - view manager class
219 \li PVGUI_Viewer - view model class
220 \li PVGUI_ViewWindow - view window class that acts as a parent for %pqViewManager
222 Single instances of PVGUI_ViewManager and PVGUI_ViewWindow classes are created by \link PVGUI_Module::showView()
223 PVGUI_Module::showView()\endlink method upon the first PARAVIS module activation. The same method hides the multi-view manager
224 when the module is deactivated (the user switches to another module or a study is closed).
225 A special trick is used to make PVGUI_ViewWindow the parent of %pqViewManager widget. It is created initally by %pqMainWindowCore
226 with the desktop as a parent, so when it is shown PVGUI_ViewWindow instance is passed to its setParent() method. In
227 \link PVGUI_ViewWindow::~PVGUI_ViewWindow() PVGUI_ViewWindow::~PVGUI_ViewWindow()\endlink the parent is nullified to avoid deletion
228 of %pqViewManager widget that would break %pqMainWindowCore class.
230 <h3>ParaView plugins</h3>
231 ParaView server and client plugins are managed by %pqMainWindowCore slots that has full access to PARAVIS menus and toolbars.
232 As a result they appears automatically in PARAVIS menus and toolbars if loaded successfully.
237 \brief Implementation
238 SALOME module wrapping ParaView GUI.
242 \brief Constructor. Sets the default name for the module.
244 PVGUI_Module::PVGUI_Module()
245 : SalomeApp_Module( "PARAVIS" ),
246 LightApp_Module( "PARAVIS" ),
247 // Implementation( 0 ),
248 mySelectionControlsTb( -1 ),
249 mySourcesMenuId( -1 ),
250 myFiltersMenuId( -1 ),
252 myToolbarsMenuId(-1),
259 Q_INIT_RESOURCE( PVGUI );
261 ParavisModule = this;
264 QString aDestPath = QString( "%1/.config/%2/Macros" ).arg( QDir::homePath() ).arg( QApplication::applicationName() );
268 QDir aDestDir(aDestPath);
269 QStringList aDestFiles = aDestDir.entryList(aFilter, QDir::Files);
270 foreach (QString aStr, aDestFiles) {
271 aDestDir.remove(aStr);
278 PVGUI_Module::~PVGUI_Module()
285 \brief Initialize module. Creates menus, prepares context menu, etc.
286 \param app SALOME GUI application instance
288 void PVGUI_Module::initialize( CAM_Application* app )
290 SalomeApp_Module::initialize( app );
292 // Create ParaViS actions
294 // Create ParaViS menus
297 // Uncomment to debug ParaView initialization
298 // "aa" used instead of "i" as GDB doesn't like "i" variables :)
306 // Initialize ParaView client
309 // Create GUI elements (menus, toolbars, dock widgets)
310 //if ( !Implementation ){
311 SalomeApp_Application* anApp = getApp();
312 SUIT_Desktop* aDesktop = anApp->desktop();
314 // connect(aDesktop, SIGNAL()
316 // Remember current state of desktop toolbars
317 QList<QToolBar*> foreignToolbars = aDesktop->findChildren<QToolBar*>();
319 // Simulate ParaView client main window
320 //Implementation = new pqImplementation( aDesktop );
328 // new pqParaViewBehaviors(anApp->desktop(), this);
329 // Has to be replaced in order to exclude using of pqQtMessageHandlerBehaviour
330 // Start pqParaViewBehaviors
331 // Register ParaView interfaces.
332 //pqPluginManager* pgm = pqApplicationCore::instance()->getPluginManager();
333 pqInterfaceTracker* pgm = pqApplicationCore::instance()->interfaceTracker();
335 // * adds support for standard paraview views.
336 pgm->addInterface(new pqStandardViewModules(pgm));
337 pgm->addInterface(new pqStandardSummaryPanelImplementation(pgm));
339 // Load plugins distributed with application.
340 pqApplicationCore::instance()->loadDistributedPlugins();
342 // Define application behaviors.
343 //new pqQtMessageHandlerBehavior(this);
344 new pqDataTimeStepBehavior(this);
345 new pqViewFrameActionsBehavior(this);
346 new pqSpreadSheetVisibilityBehavior(this);
347 new pqPipelineContextMenuBehavior(this);
348 new pqDefaultViewBehavior(this);
349 new pqAlwaysConnectedBehavior(this);
350 new pqPVNewSourceBehavior(this);
351 new pqDeleteBehavior(this);
352 new pqUndoRedoBehavior(this);
353 new pqCrashRecoveryBehavior(this);
354 new pqAutoLoadPluginXMLBehavior(this);
355 new pqPluginDockWidgetsBehavior(aDesktop);
356 //new pqVerifyRequiredPluginBehavior(this);
357 new pqPluginActionGroupBehavior(aDesktop);
358 //new pqFixPathsInStateFilesBehavior(this);
359 new pqCommandLineOptionsBehavior(this);
360 new pqPersistentMainWindowStateBehavior(aDesktop);
361 new pqObjectPickingBehavior(aDesktop);
362 new pqCollaborationBehavior(this);
364 // Setup quick-launch shortcuts.
365 QShortcut *ctrlSpace = new QShortcut(Qt::CTRL + Qt::Key_Space, aDesktop);
366 QObject::connect(ctrlSpace, SIGNAL(activated()),
367 pqApplicationCore::instance(), SLOT(quickLaunch()));
368 QShortcut *altSpace = new QShortcut(Qt::ALT + Qt::Key_Space, aDesktop);
369 QObject::connect(altSpace, SIGNAL(activated()),
370 pqApplicationCore::instance(), SLOT(quickLaunch()));
371 // End pqParaViewBehaviors
374 SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
375 QString aPath = resMgr->stringValue("resources", "PARAVIS", QString());
376 if (!aPath.isNull()) {
377 MyCoreApp->loadConfiguration(aPath + QDir::separator() + "ParaViewFilters.xml");
378 MyCoreApp->loadConfiguration(aPath + QDir::separator() + "ParaViewReaders.xml");
379 MyCoreApp->loadConfiguration(aPath + QDir::separator() + "ParaViewSources.xml");
380 MyCoreApp->loadConfiguration(aPath + QDir::separator() + "ParaViewWriters.xml");
383 // Force creation of engine
384 PARAVIS::GetParavisGen(this);
387 // Find created toolbars
388 QCoreApplication::processEvents();
390 QList<QToolBar*> allToolbars = aDesktop->findChildren<QToolBar*>();
391 foreach(QToolBar* aBar, allToolbars) {
392 if (!foreignToolbars.contains(aBar)) {
393 myToolbars[aBar] = true;
394 myToolbarBreaks[aBar] = false;
395 aBar->setVisible(false);
396 aBar->toggleViewAction()->setVisible(false);
403 // we need to start trace after connection is done
404 connect(pqApplicationCore::instance()->getObjectBuilder(), SIGNAL(finishedAddingServer(pqServer*)),
405 this, SLOT(onFinishedAddingServer(pqServer*)));
407 SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr();
408 bool isStop = aResourceMgr->booleanValue( "PARAVIS", "stop_trace", false );
409 // start timer to activate trace in a proper moment
413 this->VTKConnect = vtkEventQtSlotConnect::New();
414 vtkProcessModule* pm = vtkProcessModule::GetProcessModule();
416 this->VTKConnect->Connect(pm, vtkCommand::StartEvent,
417 this, SLOT(onStartProgress()));
418 this->VTKConnect->Connect(pm, vtkCommand::EndEvent,
419 this, SLOT(onEndProgress()));
422 void PVGUI_Module::onStartProgress()
424 QApplication::setOverrideCursor(Qt::WaitCursor);
427 void PVGUI_Module::onEndProgress()
429 QApplication::restoreOverrideCursor();
432 void PVGUI_Module::onFinishedAddingServer(pqServer* /*server*/)
434 SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr();
435 bool isStop = aResourceMgr->booleanValue( "PARAVIS", "stop_trace", false );
441 \brief Launches a tracing of current server
443 void PVGUI_Module::timerEvent(QTimerEvent* te )
446 PyInterp_Dispatcher* aDispatcher = PyInterp_Dispatcher::Get();
447 if ( !aDispatcher->IsBusy() ) {
448 pqPythonManager* manager = qobject_cast<pqPythonManager*>
449 ( pqApplicationCore::instance()->manager( "PYTHON_MANAGER" ) );
451 pqPythonDialog* pyDiag = manager->pythonShellDialog();
453 pqPythonShell* shell = pyDiag->shell();
455 QString script = "from paraview import smtrace\nsmtrace.start_trace()\n";
456 shell->executeScript(script);
457 killTimer( te->timerId() );
465 void PVGUI_Module::updateMacros()
467 pqPythonManager* aPythonManager = pqPVApplicationCore::instance()->pythonManager();
468 if(!aPythonManager) {
472 QString aRootDir = getenv("PARAVIS_ROOT_DIR");
474 QString aSourcePath = aRootDir + "/bin/salome/Macro";
479 QDir aSourceDir(aSourcePath);
480 QStringList aSourceFiles = aSourceDir.entryList(aFilter, QDir::Files);
481 foreach (QString aStr, aSourceFiles) {
482 aPythonManager->addMacro(aSourcePath + "/" + aStr);
488 \brief Get list of compliant dockable GUI elements
489 \param m map to be filled in ("type":"default_position")
491 void PVGUI_Module::windows( QMap<int, int>& m ) const
493 m.insert( LightApp_Application::WT_ObjectBrowser, Qt::LeftDockWidgetArea );
494 m.insert( LightApp_Application::WT_PyConsole, Qt::BottomDockWidgetArea );
495 // ParaView diagnostic output redirected here
496 m.insert( LightApp_Application::WT_LogWindow, Qt::BottomDockWidgetArea );
500 \brief Static method, performs initialization of ParaView session.
501 \return \c true if ParaView has been initialized successfully, otherwise false
503 bool PVGUI_Module::pvInit()
505 // if ( !pqImplementation::Core ){
507 // Obtain command-line arguments
510 QString aOptions = getenv("PARAVIS_OPTIONS");
511 QStringList aOptList = aOptions.split(":", QString::SkipEmptyParts);
512 argv = new char*[aOptList.size() + 1];
513 QStringList args = QApplication::arguments();
514 argv[0] = (args.size() > 0)? strdup(args[0].toLatin1().constData()) : strdup("paravis");
517 foreach (QString aStr, aOptList) {
518 argv[argc] = strdup( aStr.toLatin1().constData() );
521 MyCoreApp = new pqPVApplicationCore (argc, argv);
522 if (MyCoreApp->getOptions()->GetHelpSelected() ||
523 MyCoreApp->getOptions()->GetUnknownArgument() ||
524 MyCoreApp->getOptions()->GetErrorMessage() ||
525 MyCoreApp->getOptions()->GetTellVersion()) {
529 // Not sure why this is needed. Andy added this ages ago with comment saying
530 // needed for Mac apps. Need to check that it's indeed still required.
531 QDir dir(QApplication::applicationDirPath());
534 QApplication::addLibraryPath(dir.absolutePath());
535 // Load required application plugins.
536 QString plugin_string = "";
537 QStringList plugin_list = plugin_string.split(';',QString::SkipEmptyParts);
538 pqBrandPluginsLoader loader;
539 if (loader.loadPlugins(plugin_list) == false) {
540 printf("Failed to load required plugins for this application\n");
544 // Load optional plugins.
546 plugin_list = plugin_string.split(';',QString::SkipEmptyParts);
547 loader.loadPlugins(plugin_list, true); //quietly skip not-found plugins.
549 // End of Initializer code
551 vtkOutputWindow::SetInstance(PVGUI_OutputWindowAdapter::New());
553 new pqTabbedMultiViewWidget(); // it registers as "MULTIVIEW_WIDGET on creation
555 for (int i = 0; i < argc; i++)
564 \brief Shows (toShow = true) or hides ParaView view window
566 void PVGUI_Module::showView( bool toShow )
568 SalomeApp_Application* anApp = getApp();
569 PVGUI_ViewManager* viewMgr =
570 dynamic_cast<PVGUI_ViewManager*>( anApp->getViewManager( PVGUI_Viewer::Type(), false ) );
572 viewMgr = new PVGUI_ViewManager( anApp->activeStudy(), anApp->desktop() );
573 anApp->addViewManager( viewMgr );
574 connect( viewMgr, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
575 anApp, SLOT( onCloseView( SUIT_ViewManager* ) ) );
578 PVGUI_ViewWindow* pvWnd = dynamic_cast<PVGUI_ViewWindow*>( viewMgr->getActiveView() );
580 pvWnd = dynamic_cast<PVGUI_ViewWindow*>( viewMgr->createViewWindow() );
583 pvWnd->setShown( toShow );
584 if ( toShow ) pvWnd->setFocus();
588 \brief Slot to show help for proxy.
590 void PVGUI_Module::showHelpForProxy( const QString& groupname, const QString& proxyname )
592 pqHelpReaction::showProxyHelp(groupname, proxyname);
597 \brief Slot to show the waiting state.
599 void PVGUI_Module::onPreAccept()
601 getApp()->desktop()->statusBar()->showMessage(tr("STB_PREACCEPT"));
602 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
606 \brief Slot to show the ready state.
608 void PVGUI_Module::onPostAccept()
610 getApp()->desktop()->statusBar()->showMessage(tr("STB_POSTACCEPT"), 2000);
611 QTimer::singleShot(0, this, SLOT(endWaitCursor()));
615 \brief Slot to switch off wait cursor.
617 void PVGUI_Module::endWaitCursor()
619 QApplication::restoreOverrideCursor();
623 \brief Returns the ParaView multi-view manager.
625 pqTabbedMultiViewWidget* PVGUI_Module::getMultiViewManager() const
627 return qobject_cast<pqTabbedMultiViewWidget*>(pqApplicationCore::instance()->manager("MULTIVIEW_WIDGET"));
631 static void ParavisMessageOutput(QtMsgType type, const char *msg)
636 vtkOutputWindow::GetInstance()->DisplayText(msg);
639 vtkOutputWindow::GetInstance()->DisplayErrorText(msg);
642 vtkOutputWindow::GetInstance()->DisplayErrorText(msg);
645 vtkOutputWindow::GetInstance()->DisplayErrorText(msg);
653 \brief Activate module.
654 \param study current study
655 \return \c true if activaion is done successfully or 0 to prevent
658 bool PVGUI_Module::activateModule( SUIT_Study* study )
660 myOldMsgHandler = qInstallMsgHandler(ParavisMessageOutput);
662 bool isDone = SalomeApp_Module::activateModule( study );
663 if ( !isDone ) return false;
666 if ( mySourcesMenuId != -1 ) menuMgr()->show(mySourcesMenuId);
667 if ( myFiltersMenuId != -1 ) menuMgr()->show(myFiltersMenuId);
668 if ( myFiltersMenuId != -1 ) menuMgr()->show(myMacrosMenuId);
669 if ( myFiltersMenuId != -1 ) menuMgr()->show(myToolbarsMenuId);
670 setMenuShown( true );
671 setToolShown( true );
673 restoreDockWidgetsState();
675 QMenu* aMenu = menuMgr()->findMenu( myRecentMenuId );
677 QList<QAction*> anActns = aMenu->actions();
678 for (int i = 0; i < anActns.size(); ++i) {
679 QAction* a = anActns.at(i);
685 if ( myRecentMenuId != -1 ) menuMgr()->show(myRecentMenuId);
692 \brief Deactivate module.
693 \param study current study
694 \return \c true if deactivaion is done successfully or 0 to prevent
695 deactivation on error
697 bool PVGUI_Module::deactivateModule( SUIT_Study* study )
699 QMenu* aMenu = menuMgr()->findMenu( myRecentMenuId );
701 QList<QAction*> anActns = aMenu->actions();
702 for (int i = 0; i < anActns.size(); ++i) {
703 QAction* a = anActns.at(i);
705 a->setVisible(false);
709 QList<QDockWidget*> aStreamingViews = application()->desktop()->findChildren<QDockWidget*>("pqStreamingControls");
710 foreach(QDockWidget* aView, aStreamingViews) {
711 if (!myDockWidgets.contains(aView))
712 myDockWidgets[aView] = aView->isVisible();
715 /*if (pqImplementation::helpWindow) {
716 pqImplementation::helpWindow->hide();
720 menuMgr()->hide(myRecentMenuId);
721 menuMgr()->hide(mySourcesMenuId);
722 menuMgr()->hide(myFiltersMenuId);
723 menuMgr()->hide(myMacrosMenuId);
724 menuMgr()->hide(myToolbarsMenuId);
725 setMenuShown( false );
726 setToolShown( false );
729 saveDockWidgetsState();
732 qInstallMsgHandler(myOldMsgHandler);
734 return SalomeApp_Module::deactivateModule( study );
739 \brief Called when application is closed.
741 Process finalize application functionality from ParaView in order to save server settings
742 and nullify application pointer if the application is being closed.
744 \param theApp application
746 void PVGUI_Module::onApplicationClosed( SUIT_Application* theApp )
748 pqApplicationCore::instance()->settings()->sync();
749 int aAppsNb = SUIT_Session::session()->applications().size();
751 deleteTemporaryFiles();
752 MyCoreApp->deleteLater();
754 CAM_Module::onApplicationClosed(theApp);
759 \brief Called when study is closed.
761 Removes data model from the \a study.
763 \param study study being closed
765 void PVGUI_Module::studyClosed(SUIT_Study* study)
767 clearParaviewState();
769 SalomeApp_Module::studyClosed(study);
773 \brief Called when study is opened.
775 void PVGUI_Module::onModelOpened()
777 _PTR(Study) studyDS = PARAVIS::GetCStudy(this);
782 _PTR(SComponent) paravisComp =
783 studyDS->FindComponent(PARAVIS::GetParavisGen(this)->ComponentDataType());
788 _PTR(ChildIterator) anIter(studyDS->NewChildIterator(paravisComp));
789 for (; anIter->More(); anIter->Next()) {
790 _PTR(SObject) aSObj = anIter->Value();
791 _PTR(GenericAttribute) anAttr;
792 if (!aSObj->FindAttribute(anAttr, "AttributeLocalID")) {
795 _PTR(AttributeLocalID) anID(anAttr);
796 if (anID->Value() == PVSTATEID) {
803 \brief Returns IOR of current engine
805 QString PVGUI_Module::engineIOR() const
807 CORBA::String_var anIOR = PARAVIS::GetParavisGen(this)->GetIOR();
808 return QString(anIOR.in());
813 \brief Open file of format supported by ParaView
815 void PVGUI_Module::openFile(const char* theName)
819 pqLoadDataReaction::loadData(aFiles);
822 void PVGUI_Module::executeScript(const char *script)
825 pqPythonManager* manager = qobject_cast<pqPythonManager*>(
826 pqApplicationCore::instance()->manager("PYTHON_MANAGER"));
828 pqPythonDialog* pyDiag = manager->pythonShellDialog();
830 pyDiag->runString(script);
837 \brief Returns trace string
839 static const QString MYReplaceStr("paraview.simple");
840 static const QString MYReplaceImportStr("except: from pvsimple import *");
841 QString PVGUI_Module::getTraceString()
845 pqPythonManager* manager = qobject_cast<pqPythonManager*>(
846 pqApplicationCore::instance()->manager("PYTHON_MANAGER"));
848 pqPythonDialog* pyDiag = manager->pythonShellDialog();
850 pyDiag->runString("from paraview import smtrace\n"
851 "__smtraceString = smtrace.get_trace_string()\n");
852 pyDiag->shell()->makeCurrent();
853 PyObject* main_module = PyImport_AddModule((char*)"__main__");
854 PyObject* global_dict = PyModule_GetDict(main_module);
855 PyObject* string_object = PyDict_GetItemString(global_dict, "__smtraceString");
856 char* string_ptr = string_object ? PyString_AsString(string_object) : 0;
858 traceString = string_ptr;
860 pyDiag->shell()->releaseControl();
863 if ((!traceString.isNull()) && traceString.length() != 0) {
864 int aPos = traceString.indexOf(MYReplaceStr);
866 traceString = traceString.replace(aPos, MYReplaceStr.length(), "pvsimple");
867 aPos = traceString.indexOf(MYReplaceStr, aPos);
869 int aImportPos = traceString.indexOf(MYReplaceImportStr);
872 traceString = traceString.replace(aImportPos, MYReplaceImportStr.length(), "except:\n import pvsimple\n from pvsimple import *");
880 \brief Saves trace string to disk file
882 void PVGUI_Module::saveTrace(const char* theName)
885 if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
886 MESSAGE( "Could not open file:" << theName );
889 QTextStream out(&file);
890 out << getTraceString();
895 \brief Saves ParaView state to a disk file
897 void PVGUI_Module::saveParaviewState(const char* theFileName)
899 pqApplicationCore::instance()->saveState(theFileName);
903 \brief Delete all objects for Paraview Pipeline Browser
905 void PVGUI_Module::clearParaviewState()
907 QAction* deleteAllAction = action(DeleteAllId);
908 if (deleteAllAction) {
909 deleteAllAction->activate(QAction::Trigger);
914 \brief Restores ParaView state from a disk file
916 If toClear == true, the current ojects will be deleted
918 void PVGUI_Module::loadParaviewState(const char* theFileName)
920 pqApplicationCore::instance()->loadState(theFileName, getActiveServer());
924 \brief Imports MED data from VISU module by data entry
926 void PVGUI_Module::onImportFromVisu(QString theEntry)
929 SUIT_OverrideCursor aWaitCursor;
932 SalomeApp_Study* activeStudy = dynamic_cast<SalomeApp_Study*>(application()->activeStudy());
933 if(!activeStudy) return;
935 // get SALOMEDS client study
936 _PTR(Study) aStudy = activeStudy->studyDS();
939 // find VISU component in a study
940 _PTR(SComponent) aVisuComp = aStudy->FindComponent( "VISU" );
941 if(!aVisuComp) return;
943 // get SObject client by entry
944 _PTR(SObject) aSObj = aStudy->FindObjectID(qPrintable(theEntry));
948 SALOMEDS_SObject* aSObject = _CAST(SObject, aSObj);
949 if ( !aSObject ) return;
952 SALOME_NamingService* aNamingService = SalomeApp_Application::namingService();
953 SALOME_LifeCycleCORBA aLCC(aNamingService);
955 Engines::EngineComponent_var aComponent = aLCC.FindOrLoad_Component("FactoryServer","VISU");
956 VISU::VISU_Gen_var aVISU = VISU::VISU_Gen::_narrow(aComponent);
957 if(CORBA::is_nil(aVISU)) return;
959 _PTR(StudyBuilder) aStudyBuilder = aStudy->NewBuilder();
960 aStudyBuilder->LoadWith( aVisuComp, SalomeApp_Application::orb()->object_to_string(aVISU) );
962 // get VISU result object
963 CORBA::Object_var aResultObject = aSObject->GetObject();
964 if (CORBA::is_nil(aResultObject)) return;
965 VISU::Result_var aResult = VISU::Result::_narrow( aResultObject );
966 if (CORBA::is_nil(aResult)) return;
968 // export VISU result to the MED file
969 std::string aTmpDir = SALOMEDS_Tool::GetTmpDir();
970 std::string aFileName = aSObject->GetName();
971 std::string aFilePath = aTmpDir + aFileName;
973 if (aResult->ExportMED(aFilePath.c_str())) {
974 openFile(aFilePath.c_str());
975 myTemporaryFiles.append(QString(aFilePath.c_str()));
978 MESSAGE("Visu module is not found.");
983 \brief Deletes temporary files created during import operation from VISU
985 void PVGUI_Module::deleteTemporaryFiles()
987 foreach(QString aFile, myTemporaryFiles) {
988 if (QFile::exists(aFile)) {
989 QFile::remove(aFile);
996 \brief Returns current active ParaView server
998 pqServer* PVGUI_Module::getActiveServer()
1000 return pqApplicationCore::instance()->getActiveServer();
1005 \brief Creates PARAVIS preference pane
1007 void PVGUI_Module::createPreferences()
1009 // Paraview settings tab
1010 int aParaViewSettingsTab = addPreference( tr( "TIT_PVIEWSETTINGS" ) );
1011 int aPanel = addPreference(QString(), aParaViewSettingsTab, LightApp_Preferences::UserDefined, "PARAVIS", "");
1012 setPreferenceProperty(aPanel, "content", (qint64)(new PVGUI_ParaViewSettingsPane()));
1014 // Paravis settings tab
1015 int aParaVisSettingsTab = addPreference( tr( "TIT_PVISSETTINGS" ) );
1016 addPreference( tr( "PREF_STOP_TRACE" ), aParaVisSettingsTab, LightApp_Preferences::Bool, "PARAVIS", "stop_trace");
1018 int aSaveType = addPreference(tr( "PREF_SAVE_TYPE_LBL" ), aParaVisSettingsTab,
1019 LightApp_Preferences::Selector,
1020 "PARAVIS", "savestate_type");
1021 QList<QVariant> aIndices;
1022 QStringList aStrings;
1024 aStrings<<tr("PREF_SAVE_TYPE_0");
1025 aStrings<<tr("PREF_SAVE_TYPE_1");
1026 aStrings<<tr("PREF_SAVE_TYPE_2");
1027 setPreferenceProperty(aSaveType, "strings", aStrings);
1028 setPreferenceProperty(aSaveType, "indexes", aIndices);
1032 \brief Creates ParaViS context menu popup
1034 void PVGUI_Module::contextMenuPopup(const QString& theClient, QMenu* theMenu, QString& theTitle)
1036 SalomeApp_Module::contextMenuPopup(theClient, theMenu, theTitle);
1038 // Check if we are in Object Browser
1039 SUIT_DataBrowser* ob = getApp()->objectBrowser();
1040 bool isOBClient = (ob && theClient == ob->popupClientType());
1045 // Get list of selected objects
1046 LightApp_SelectionMgr* aSelectionMgr = getApp()->selectionMgr();
1047 SALOME_ListIO aListIO;
1048 aSelectionMgr->selectedObjects(aListIO);
1049 if (aListIO.Extent() == 1 && aListIO.First()->hasEntry()) {
1050 QString entry = QString(aListIO.First()->getEntry());
1053 SalomeApp_Study* activeStudy =
1054 dynamic_cast<SalomeApp_Study*>(getApp()->activeStudy());
1059 // Get SALOMEDS client study
1060 _PTR(Study) studyDS = activeStudy->studyDS();
1065 QString paravisDataType(PARAVIS::GetParavisGen(this)->ComponentDataType());
1066 if(activeStudy && activeStudy->isComponent(entry) &&
1067 activeStudy->componentDataType(entry) == paravisDataType) {
1068 // ParaViS module object
1069 theMenu->addSeparator();
1070 theMenu->addAction(action(SaveStatePopupId));
1073 // Try to get state object
1074 _PTR(SObject) stateSObj =
1075 studyDS->FindObjectID(entry.toLatin1().constData());
1081 _PTR(GenericAttribute) anAttr;
1082 if (!stateSObj->FindAttribute(anAttr, "AttributeLocalID")) {
1086 _PTR(AttributeLocalID) anID(anAttr);
1088 if (anID->Value() == PVSTATEID) {
1089 // Paraview state object
1090 theMenu->addSeparator();
1091 theMenu->addAction(action(AddStatePopupId));
1092 theMenu->addAction(action(CleanAndAddStatePopupId));
1093 theMenu->addSeparator();
1094 theMenu->addAction(action(ParaVisRenameId));
1095 theMenu->addAction(action(ParaVisDeleteId));
1101 void PVGUI_Module::onShowTrace()
1103 if (!myTraceWindow) {
1104 myTraceWindow = new pqPythonScriptEditor(getApp()->desktop());
1106 myTraceWindow->setText(getTraceString());
1107 myTraceWindow->show();
1108 myTraceWindow->raise();
1109 myTraceWindow->activateWindow();
1113 \brief Show ParaView view.
1115 void PVGUI_Module::onNewParaViewWindow()
1121 \brief Save state under the module root object.
1123 void PVGUI_Module::onSaveMultiState()
1125 // Create state study object
1127 // Get SALOMEDS client study
1128 _PTR(Study) studyDS = PARAVIS::GetCStudy(this);
1133 _PTR(SComponent) paravisComp =
1134 studyDS->FindComponent(PARAVIS::GetParavisGen(this)->ComponentDataType());
1139 // Unlock the study if it is locked
1140 bool isLocked = studyDS->GetProperties()->IsLocked();
1142 studyDS->GetProperties()->SetLocked(false);
1145 QString stateName = tr("SAVED_PARAVIEW_STATE_NAME") +
1146 QString::number(myStateCounter + 1);
1148 _PTR(StudyBuilder) studyBuilder = studyDS->NewBuilder();
1149 _PTR(SObject) newSObj = studyBuilder->NewObject(paravisComp);
1152 _PTR(GenericAttribute) anAttr;
1153 anAttr = studyBuilder->FindOrCreateAttribute(newSObj, "AttributeName");
1154 _PTR(AttributeName) nameAttr(anAttr);
1156 nameAttr->SetValue(stateName.toLatin1().constData());
1159 anAttr = studyBuilder->FindOrCreateAttribute(newSObj, "AttributeLocalID");
1160 _PTR(AttributeLocalID) localIdAttr(anAttr);
1162 localIdAttr->SetValue(PVSTATEID);
1165 QString stateEntry = QString::fromStdString(newSObj->GetID());
1167 // File name for state saving
1168 QString tmpDir = QString::fromStdString(SALOMEDS_Tool::GetTmpDir());
1169 QString fileName = QString("%1_paravisstate:%2").arg(tmpDir,
1172 anAttr = studyBuilder->FindOrCreateAttribute(newSObj, "AttributeString");
1173 _PTR(AttributeString) stringAttr(anAttr);
1175 stringAttr->SetValue(fileName.toLatin1().constData());
1177 // Lock the study back if necessary
1179 studyDS->GetProperties()->SetLocked(true);
1183 saveParaviewState(fileName.toLatin1().constData());
1184 myTemporaryFiles.append(fileName);
1186 // Increment the counter
1193 \brief Restore the selected state by merging with the current one.
1195 void PVGUI_Module::onAddState()
1197 loadSelectedState(false);
1201 \brief Clean the current state and restore the selected one.
1203 void PVGUI_Module::onCleanAddState()
1205 loadSelectedState(true);
1209 \brief Rename the selected object.
1211 void PVGUI_Module::onRename()
1213 LightApp_SelectionMgr* aSelectionMgr = getApp()->selectionMgr();
1214 SALOME_ListIO aListIO;
1215 aSelectionMgr->selectedObjects(aListIO);
1217 if (aListIO.Extent() == 1 && aListIO.First()->hasEntry()) {
1218 std::string entry = aListIO.First()->getEntry();
1220 // Get SALOMEDS client study
1221 _PTR(Study) studyDS = PARAVIS::GetCStudy(this);
1226 // Unlock the study if it is locked
1227 bool isLocked = studyDS->GetProperties()->IsLocked();
1229 studyDS->GetProperties()->SetLocked(false);
1232 // Rename the selected state object
1233 _PTR(SObject) stateSObj = studyDS->FindObjectID(entry);
1238 _PTR(GenericAttribute) anAttr;
1239 if (stateSObj->FindAttribute(anAttr, "AttributeName")) {
1240 _PTR(AttributeName) nameAttr (anAttr);
1242 LightApp_NameDlg::getName(getApp()->desktop(), nameAttr->Value().c_str());
1243 if (!newName.isEmpty()) {
1244 nameAttr->SetValue(newName.toLatin1().constData());
1245 aListIO.First()->setName(newName.toLatin1().constData());
1249 // Lock the study back if necessary
1251 studyDS->GetProperties()->SetLocked(true);
1254 // Update object browser
1261 \brief Delete the selected objects.
1263 void PVGUI_Module::onDelete()
1265 LightApp_SelectionMgr* aSelectionMgr = getApp()->selectionMgr();
1266 SALOME_ListIO aListIO;
1267 aSelectionMgr->selectedObjects(aListIO);
1269 if (aListIO.Extent() == 1 && aListIO.First()->hasEntry()) {
1270 std::string entry = aListIO.First()->getEntry();
1272 // Get SALOMEDS client study
1273 _PTR(Study) studyDS = PARAVIS::GetCStudy(this);
1278 // Unlock the study if it is locked
1279 bool isLocked = studyDS->GetProperties()->IsLocked();
1281 studyDS->GetProperties()->SetLocked(false);
1284 // Remove the selected state from the study
1285 _PTR(StudyBuilder) studyBuilder = studyDS->NewBuilder();
1286 _PTR(SObject) stateSObj = studyDS->FindObjectID(entry);
1287 studyBuilder->RemoveObject(stateSObj);
1289 // Lock the study back if necessary
1291 studyDS->GetProperties()->SetLocked(true);
1294 // Update object browser
1300 \brief Discover help project files from the resources.
1301 \return name of the help file.
1303 QString PVGUI_Module::getHelpFileName() {
1304 QString aPVHome(getenv("PVHOME"));
1305 if (aPVHome.isNull()) {
1306 qWarning("Wariable PVHOME is not defined");
1309 QChar aSep = QDir::separator();
1310 //PARAVIEW_VERSION from the vtkPVConfig.h file
1311 QString aFileName = aPVHome + aSep + "share" + aSep + "doc" + aSep + "paraview-"+ PARAVIEW_VERSION + aSep + "paraview.qch";
1317 \brief Load selected paraview state
1319 If toClear == true, the current state will be cleared
1321 void PVGUI_Module::loadSelectedState(bool toClear)
1325 LightApp_SelectionMgr* aSelectionMgr = getApp()->selectionMgr();
1326 SALOME_ListIO aListIO;
1327 aSelectionMgr->selectedObjects(aListIO);
1329 if (aListIO.Extent() == 1 && aListIO.First()->hasEntry()) {
1330 std::string entry = aListIO.First()->getEntry();
1332 // Get SALOMEDS client study
1333 _PTR(Study) studyDS = PARAVIS::GetCStudy(this);
1339 _PTR(SObject) stateSObj = studyDS->FindObjectID(entry);
1340 _PTR(GenericAttribute) anAttr;
1341 if (!stateSObj->FindAttribute(anAttr, "AttributeLocalID")) {
1344 _PTR(AttributeLocalID) anID(anAttr);
1345 if (!anID->Value() == PVSTATEID) {
1349 // Get state file name
1350 if (stateSObj->FindAttribute(anAttr, "AttributeString")) {
1351 _PTR(AttributeString) aStringAttr(anAttr);
1352 QString stringValue(aStringAttr->Value().c_str());
1354 if (QFile::exists(stringValue)) {
1355 fileName = stringValue;
1360 if (!fileName.isEmpty()) {
1362 clearParaviewState();
1365 loadParaviewState(fileName.toLatin1().constData());
1368 SUIT_MessageBox::critical(getApp()->desktop(),
1370 tr("ERR_STATE_CANNOT_BE_RESTORED"));
1375 \fn CAM_Module* createModule();
1376 \brief Export module instance (factory function).
1377 \return new created instance of the module
1381 #define PVGUI_EXPORT __declspec(dllexport)
1383 #define PVGUI_EXPORT
1387 PVGUI_EXPORT CAM_Module* createModule() {
1388 return new PVGUI_Module();
1391 PVGUI_EXPORT char* getModuleVersion() {
1392 return (char*)PARAVIS_VERSION_STR;