1 // PARAVIS : ParaView wrapper SALOME module
3 // Copyright (C) 2010-2015 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, or (at your option) any later version.
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
23 #define PARAVIS_MODULE_NAME "PARAVIS"
25 #include <Standard_math.hxx> // E.A. must be included before Python.h to fix compilation on windows
27 #undef HAVE_FINITE // VSR: avoid compilation warning on Linux : "HAVE_FINITE" redefined
29 #include <vtkPython.h> // Python first
30 #include "PVGUI_Module.h"
32 #include CORBA_SERVER_HEADER(SALOME_ModuleCatalog)
33 #include CORBA_SERVER_HEADER(SALOMEDS)
35 #include "PVViewer_ViewManager.h"
36 #include "PVViewer_ViewWindow.h"
37 #include "PVViewer_ViewModel.h"
38 #include "PVGUI_Tools.h"
39 #include "PVGUI_ParaViewSettingsPane.h"
40 #include "PVViewer_GUIElements.h"
41 #include "PVViewer_EngineWrapper.h"
42 #include "PVGUI_DataModel.h"
45 #include <utilities.h>
46 #include <SUIT_DataBrowser.h>
47 #include <SUIT_Desktop.h>
48 #include <SUIT_MessageBox.h>
49 #include <SUIT_ResourceMgr.h>
50 #include <SUIT_Session.h>
51 #include <SUIT_OverrideCursor.h>
52 #include <SUIT_ExceptionHandler.h>
54 #include <SALOME_LifeCycleCORBA.hxx>
55 #include <SALOMEDS_SObject.hxx>
57 #include <LightApp_SelectionMgr.h>
58 #include <LightApp_NameDlg.h>
59 #include <LightApp_Application.h>
60 #include <SalomeApp_Application.h> // should ultimately be a LightApp only
61 #include <SalomeApp_Study.h>
62 #include <SALOME_ListIO.hxx>
63 #include <SALOMEDS_Tool.hxx>
64 #include <Utils_ORB_INIT.hxx>
65 #include <Utils_SINGLETON.hxx>
67 #include <QtxActionMenuMgr.h>
68 #include <QtxActionToolMgr.h>
70 #include <PARAVIS_version.h>
76 #include <QApplication>
82 #include <QInputDialog>
86 #include <QStringList>
89 #include <QTextStream>
91 #include <QDockWidget>
92 #include <QHelpEngine>
95 #include <vtkPVConfig.h> // for symbol PARAVIEW_VERSION
96 #include <vtkProcessModule.h>
97 #include <vtkPVSession.h>
98 #include <vtkPVProgressHandler.h>
99 #include <vtkOutputWindow.h>
100 #include <vtkEventQtSlotConnect.h>
102 #include <vtkSMProxy.h>
103 #include <vtkSmartPointer.h>
104 #include <vtkSMSession.h>
105 #include <vtkSMTrace.h>
106 #include <vtkSMSessionProxyManager.h>
107 #include <vtkSMParaViewPipelineController.h>
109 #include <pqApplicationCore.h>
110 #include <pqPVApplicationCore.h>
111 #include <pqObjectBuilder.h>
112 #include <pqOptions.h>
113 #include <pqSettings.h>
114 #include <pqServer.h>
115 #include <pqUndoStack.h>
116 #include <pqTabbedMultiViewWidget.h>
117 #include <pqActiveObjects.h>
118 #include <pqHelpReaction.h>
119 #include <pqPluginManager.h>
120 #include <pqPythonDialog.h>
121 #include <pqPythonManager.h>
122 #include <pqLoadDataReaction.h>
123 #include <pqPythonScriptEditor.h>
124 #include <pqDataRepresentation.h>
125 #include <pqDisplayColorWidget.h>
126 #include <pqColorToolbar.h>
127 #include <pqScalarBarVisibilityReaction.h>
128 #include <pqServerResource.h>
129 #include <pqServerConnectReaction.h>
130 #include <pqPluginManager.h>
131 #include <pqVCRToolbar.h>
132 #include <pqAnimationScene.h>
133 #include <pqServerManagerModel.h>
134 #include <pqAnimationTimeToolbar.h>
136 //----------------------------------------------------------------------------
137 PVGUI_Module* ParavisModule = 0;
138 PVSERVER_ORB::PVSERVER_Gen_var PVGUI_Module::MyEngine;
142 This is the doxygen documentation of the ParaVis module.
143 If you are looking for general information about the structure of the module, you should
144 take a look at the <a href="../index.html">Sphinx documentation</a> first.
146 The integration of ParaView into SALOME is split in two parts:
147 \li the PVViewer in the GUI module (folder *src/PVViewer*)
148 \li the ParaVis module itself (the pages you are currently browsing)
153 \brief Implementation
154 SALOME module wrapping ParaView GUI.
158 ClientFindOrCreateParavisComponent(_PTR(Study) theStudyDocument)
160 _PTR(SComponent) aSComponent = theStudyDocument->FindComponent("PVSERVER");
162 _PTR(StudyBuilder) aStudyBuilder = theStudyDocument->NewBuilder();
163 aStudyBuilder->NewCommand();
164 int aLocked = theStudyDocument->GetProperties()->IsLocked();
165 if (aLocked) theStudyDocument->GetProperties()->SetLocked(false);
166 aSComponent = aStudyBuilder->NewComponent("PVSERVER");
167 _PTR(GenericAttribute) anAttr =
168 aStudyBuilder->FindOrCreateAttribute(aSComponent, "AttributeName");
169 _PTR(AttributeName) aName (anAttr);
171 ORB_INIT& init = *SINGLETON_<ORB_INIT>::Instance();
172 CORBA::ORB_var anORB = init( qApp->argc(), qApp->argv() );
174 SALOME_NamingService *NamingService = new SALOME_NamingService( anORB );
175 CORBA::Object_var objVarN = NamingService->Resolve("/Kernel/ModulCatalog");
176 SALOME_ModuleCatalog::ModuleCatalog_var Catalogue =
177 SALOME_ModuleCatalog::ModuleCatalog::_narrow(objVarN);
178 SALOME_ModuleCatalog::Acomponent_var Comp = Catalogue->GetComponent( "PVSERVER" );
179 if (!Comp->_is_nil()) {
180 aName->SetValue(Comp->componentusername());
183 anAttr = aStudyBuilder->FindOrCreateAttribute(aSComponent, "AttributePixMap");
184 _PTR(AttributePixMap) aPixmap (anAttr);
185 aPixmap->SetPixMap( "pqAppIcon16.png" );
187 // Create Attribute parameters for future using
188 anAttr = aStudyBuilder->FindOrCreateAttribute(aSComponent, "AttributeParameter");
190 aStudyBuilder->DefineComponentInstance(aSComponent, PVGUI_Module::GetCPPEngine()->GetIOR());
191 if (aLocked) theStudyDocument->GetProperties()->SetLocked(true);
192 aStudyBuilder->CommitCommand();
198 \brief Clean up function
200 Used to stop ParaView progress events when
201 exception is caught by global exception handler.
203 void paravisCleanUp()
205 if ( pqApplicationCore::instance() ) {
206 pqServer* s = pqApplicationCore::instance()->getActiveServer();
207 if ( s ) s->session()->GetProgressHandler()->CleanupPendingProgress();
212 \brief Constructor. Sets the default name for the module.
214 PVGUI_Module::PVGUI_Module()
215 : SalomeApp_Module( PARAVIS_MODULE_NAME ),
216 mySelectionControlsTb( -1 ),
217 mySourcesMenuId( -1 ),
218 myFiltersMenuId( -1 ),
220 myToolbarsMenuId(-1),
230 Q_INIT_RESOURCE( PVGUI );
232 ParavisModule = this;
234 // Clear old copies of embedded macros files
235 QString aDestPath = QString( "%1/.config/%2/Macros" ).arg( QDir::homePath() ).arg( QApplication::applicationName() );
239 QDir aDestDir(aDestPath);
240 QStringList aDestFiles = aDestDir.entryList(aFilter, QDir::Files);
241 foreach (QString aMacrosPath, getEmbeddedMacrosList()) {
242 QString aMacrosName = QFileInfo(aMacrosPath).fileName();
243 if (aDestFiles.contains(aMacrosName)) {
244 aDestDir.remove(aMacrosName);
252 PVGUI_Module::~PVGUI_Module()
254 if (myPushTraceTimer)
255 delete myPushTraceTimer;
261 * \brief Retrieve the PVSERVER CORBA engine.
262 * This uses the Python wrapper provided
263 * by the PVViewer code in GUI (class PVViewer_EngineWrapper).
266 PVViewer_EngineWrapper * PVGUI_Module::GetEngine()
268 return PVViewer_EngineWrapper::GetInstance();
272 * \brief Retrieve the PVSERVER CORBA engine.
273 * Uses directly the standard Salome C++ mechanisms
277 PVSERVER_ORB::PVSERVER_Gen_var PVGUI_Module::GetCPPEngine()
279 // initialize PARAVIS module engine (load, if necessary)
280 if ( CORBA::is_nil( MyEngine ) ) {
281 Engines::EngineComponent_var comp =
282 SalomeApp_Application::lcc()->FindOrLoad_Component( "FactoryServer", "PVSERVER" );
283 MyEngine = PVSERVER_ORB::PVSERVER_Gen::_narrow( comp );
289 \brief Create data model.
290 \return module specific data model
292 CAM_DataModel* PVGUI_Module::createDataModel()
294 return new PVGUI_DataModel( this );
298 * \brief Get the ParaView application singleton.
300 pqPVApplicationCore * PVGUI_Module::GetPVApplication()
302 return PVViewer_ViewManager::GetPVApplication();
306 \brief Initialize module. Creates menus, prepares context menu, etc.
307 \param app SALOME GUI application instance
309 void PVGUI_Module::initialize( CAM_Application* app )
311 LightApp_Module::initialize( app );
316 // Uncomment to debug ParaView initialization
317 // "aa" used instead of "i" as GDB doesn't like "i" variables :)
325 LightApp_Application* anApp = getApp();
326 SUIT_Desktop* aDesktop = anApp->desktop();
328 // Remember current state of desktop toolbars
329 QList<QToolBar*> foreignToolbars = aDesktop->findChildren<QToolBar*>();
331 // Initialize ParaView client and associated behaviors
332 // and connect to externally launched pvserver
333 PVViewer_ViewManager::ParaviewInitApp(aDesktop, anApp->logWindow());
334 myGuiElements = PVViewer_GUIElements::GetInstance(aDesktop);
336 // [ABN]: careful with the order of the GUI element creation, the loading of the configuration
337 // and the connection to the server. This order is very sensitive if one wants to make
338 // sure all menus, etc ... are correctly populated.
339 // Reference points are: ParaViewMainWindow.cxx and branded_paraview_initializer.cxx.in
346 PVViewer_ViewManager::ParaviewInitBehaviors(true, aDesktop);
348 QList<QDockWidget*> activeDocks = aDesktop->findChildren<QDockWidget*>();
349 QList<QMenu*> activeMenus = aDesktop->findChildren<QMenu*>();
351 // Setup quick-launch shortcuts.
352 QShortcut *ctrlSpace = new QShortcut(Qt::CTRL + Qt::Key_Space, aDesktop);
353 QObject::connect(ctrlSpace, SIGNAL(activated()),
354 pqApplicationCore::instance(), SLOT(quickLaunch()));
356 // Find Plugin Dock Widgets
357 QList<QDockWidget*> currentDocks = aDesktop->findChildren<QDockWidget*>();
358 QList<QDockWidget*>::iterator i;
359 for (i = currentDocks.begin(); i != currentDocks.end(); ++i) {
360 if(!activeDocks.contains(*i)) {
361 myDockWidgets[*i] = false; // hidden by default
367 // [ABN] TODO: fix this - triggers a SEGFAULT at deactivation() time.
368 // QList<QMenu*> currentMenus = aDesktop->findChildren<QMenu*>();
369 // QList<QMenu*>::iterator im;
370 // for (im = currentMenus.begin(); im != currentMenus.end(); ++im) {
371 // if(!activeMenus.contains(*im)) {
372 // QString s = (*im)->title();
373 // std::cout << " MENU "<< s.toStdString() << std::endl;
374 // myMenus.append(*im);
378 // Connect after toolbar creation, etc ... as some activations of the toolbars is triggered
379 // by the ServerConnection event:
380 PVViewer_ViewManager::ParaviewLoadConfigurations(true);
381 PVViewer_ViewManager::ConnectToExternalPVServer(aDesktop);
384 // Find created toolbars
385 QCoreApplication::processEvents();
387 // process PVViewer toolbars (might be added by PVViewer created BEFORE activating ParaVis)
388 QList<QToolBar*> pvToolbars = myGuiElements->getToolbars();
389 foreach(QToolBar* aBar, pvToolbars) {
390 if (!myToolbars.contains(aBar)) {
391 myToolbars[aBar] = true;
392 myToolbarBreaks[aBar] = false;
393 aBar->setVisible(false);
394 aBar->toggleViewAction()->setVisible(false);
398 // process other toolbars (possibly added by Paraview)
399 QList<QToolBar*> allToolbars = aDesktop->findChildren<QToolBar*>();
400 foreach(QToolBar* aBar, allToolbars) {
401 if (!foreignToolbars.contains(aBar) && !myToolbars.contains(aBar)) {
402 myToolbars[aBar] = true;
403 myToolbarBreaks[aBar] = false;
404 aBar->setVisible(false);
405 aBar->toggleViewAction()->setVisible(false);
411 SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr();
412 bool isStop = aResourceMgr->booleanValue( PARAVIS_MODULE_NAME, "stop_trace", false );
415 // Start a timer to schedule asap:
417 myInitTimer = new QTimer(aDesktop);
418 QObject::connect(myInitTimer, SIGNAL(timeout()), this, SLOT(onInitTimer()) );
419 myInitTimer->setSingleShot(true);
420 myInitTimer->start(0);
422 // Another timer to regularly push the trace onto the engine:
423 myPushTraceTimer = new QTimer(aDesktop);
424 QObject::connect(myPushTraceTimer, SIGNAL(timeout()), this, SLOT(onPushTraceTimer()) );
425 myPushTraceTimer->setSingleShot(false);
426 myPushTraceTimer->start(500);
429 this->VTKConnect = vtkEventQtSlotConnect::New();
431 vtkProcessModule* pm = vtkProcessModule::GetProcessModule();
433 vtkPVSession* pvs = dynamic_cast<vtkPVSession*>(pm->GetSession());
435 vtkPVProgressHandler* ph = pvs->GetProgressHandler();
437 this->VTKConnect->Connect(ph, vtkCommand::StartEvent,
438 this, SLOT(onStartProgress()));
439 this->VTKConnect->Connect(ph, vtkCommand::EndEvent,
440 this, SLOT(onEndProgress()));
447 * \brief Slot called when the progress bar starts.
449 void PVGUI_Module::onStartProgress()
451 // VSR 19/03/2015, issue 0023025
452 // next line is commented: it is bad idea to show wait cursor on ANY vtk event
453 // moreover, it does not work when running pvserver with --multi-client mode
454 //QApplication::setOverrideCursor(Qt::WaitCursor);
458 * \brief Slot called when the progress bar is done.
460 void PVGUI_Module::onEndProgress()
462 // VSR 19/03/2015, issue 0023025
463 // next line is commented: it is bad idea to show wait cursor on ANY vtk event
464 // moreover, it does not work when running pvserver with --multi-client mode
465 //QApplication::restoreOverrideCursor();
468 void PVGUI_Module::onDataRepresentationUpdated() {
469 SalomeApp_Study* activeStudy = dynamic_cast<SalomeApp_Study*>(application()->activeStudy());
470 if(!activeStudy) return;
472 activeStudy->Modified();
476 \brief Initialisation timer event - Starts up the Python trace
478 void PVGUI_Module::onInitTimer()
484 \brief Get list of embedded macros files
486 QStringList PVGUI_Module::getEmbeddedMacrosList()
488 QString aRootDir = getenv("PARAVIS_ROOT_DIR");
490 QString aSourcePath = aRootDir + "/bin/salome/Macro";
495 QDir aSourceDir(aSourcePath);
496 QStringList aSourceFiles = aSourceDir.entryList(aFilter, QDir::Files);
497 QStringList aFullPathSourceFiles;
498 foreach (QString aMacrosName, aSourceFiles) {
499 aFullPathSourceFiles << aSourceDir.absoluteFilePath(aMacrosName);
501 return aFullPathSourceFiles;
505 \brief Update the list of embedded macros
507 void PVGUI_Module::updateMacros()
509 pqPythonManager* aPythonManager = pqPVApplicationCore::instance()->pythonManager();
510 if(!aPythonManager) {
514 foreach (QString aStr, getEmbeddedMacrosList()) {
515 aPythonManager->addMacro(aStr);
521 \brief Get list of compliant dockable GUI elements
522 \param m map to be filled in ("type":"default_position")
524 void PVGUI_Module::windows( QMap<int, int>& m ) const
526 m.insert( LightApp_Application::WT_ObjectBrowser, Qt::LeftDockWidgetArea );
527 m.insert( LightApp_Application::WT_PyConsole, Qt::BottomDockWidgetArea );
528 // ParaView diagnostic output redirected here
529 m.insert( LightApp_Application::WT_LogWindow, Qt::BottomDockWidgetArea );
533 \brief Shows (toShow = true) or hides ParaView view window
535 void PVGUI_Module::showView( bool toShow )
537 LightApp_Application* anApp = getApp();
538 PVViewer_ViewManager* viewMgr =
539 dynamic_cast<PVViewer_ViewManager*>( anApp->getViewManager( PVViewer_Viewer::Type(), false ) );
541 viewMgr = new PVViewer_ViewManager( anApp->activeStudy(), anApp->desktop(), anApp->logWindow() );
542 anApp->addViewManager( viewMgr );
543 connect( viewMgr, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
544 anApp, SLOT( onCloseView( SUIT_ViewManager* ) ) );
547 PVViewer_ViewWindow* pvWnd = dynamic_cast<PVViewer_ViewWindow*>( viewMgr->getActiveView() );
549 pvWnd = dynamic_cast<PVViewer_ViewWindow*>( viewMgr->createViewWindow() );
550 // this also connects to the pvserver and instantiates relevant PV behaviors
553 pvWnd->setShown( toShow );
554 if ( toShow ) pvWnd->setFocus();
558 \brief Slot to show help for proxy.
560 void PVGUI_Module::showHelpForProxy( const QString& groupname, const QString& proxyname )
562 pqHelpReaction::showProxyHelp(groupname, proxyname);
567 \brief Slot to show the waiting state.
569 void PVGUI_Module::onPreAccept()
571 getApp()->desktop()->statusBar()->showMessage(tr("STB_PREACCEPT"));
572 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
576 \brief Slot to show the ready state.
578 void PVGUI_Module::onPostAccept()
580 getApp()->desktop()->statusBar()->showMessage(tr("STB_POSTACCEPT"), 2000);
581 QTimer::singleShot(0, this, SLOT(endWaitCursor()));
585 \brief Slot to switch off wait cursor.
587 void PVGUI_Module::endWaitCursor()
589 QApplication::restoreOverrideCursor();
593 \brief Handler method for the output of messages.
595 static void ParavisMessageOutput(QtMsgType type, const char *msg)
600 vtkOutputWindow::GetInstance()->DisplayText(msg);
603 vtkOutputWindow::GetInstance()->DisplayErrorText(msg);
606 vtkOutputWindow::GetInstance()->DisplayErrorText(msg);
609 vtkOutputWindow::GetInstance()->DisplayErrorText(msg);
615 \brief Activate module.
616 \param study current study
617 \return \c true if activaion is done successfully or 0 to prevent
620 bool PVGUI_Module::activateModule( SUIT_Study* study )
622 myOldMsgHandler = qInstallMsgHandler(ParavisMessageOutput);
624 SUIT_ExceptionHandler::addCleanUpRoutine( paravisCleanUp );
626 storeCommonWindowsState();
628 bool isDone = LightApp_Module::activateModule( study );
629 if ( !isDone ) return false;
632 if ( mySourcesMenuId != -1 ) menuMgr()->show(mySourcesMenuId);
633 if ( myFiltersMenuId != -1 ) menuMgr()->show(myFiltersMenuId);
634 if ( myMacrosMenuId != -1 ) menuMgr()->show(myMacrosMenuId);
635 if ( myToolbarsMenuId != -1 ) menuMgr()->show(myToolbarsMenuId);
637 // Update the various menus with the content pre-loaded in myGuiElements
638 // QMenu* srcMenu = menuMgr()->findMenu( mySourcesMenuId );
639 // myGuiElements->updateSourcesMenu(srcMenu);
640 // QMenu* filtMenu = menuMgr()->findMenu( myFiltersMenuId );
641 // myGuiElements->updateFiltersMenu(filtMenu);
642 // QMenu* macMenu = menuMgr()->findMenu( myMacrosMenuId );
643 // myGuiElements->updateMacrosMenu(macMenu);
645 setMenuShown( true );
646 setToolShown( true );
648 restoreDockWidgetsState();
650 QMenu* aMenu = menuMgr()->findMenu( myRecentMenuId );
652 QList<QAction*> anActns = aMenu->actions();
653 for (int i = 0; i < anActns.size(); ++i) {
654 QAction* a = anActns.at(i);
660 QList<QMenu*>::iterator it;
661 for (it = myMenus.begin(); it != myMenus.end(); ++it) {
662 QAction* a = (*it)->menuAction();
667 if ( myRecentMenuId != -1 ) menuMgr()->show(myRecentMenuId);
669 ClientFindOrCreateParavisComponent(PARAVIS::GetCStudy(this));
676 \brief Deactivate module.
677 \param study current study
678 \return \c true if deactivaion is done successfully or 0 to prevent
679 deactivation on error
681 bool PVGUI_Module::deactivateModule( SUIT_Study* study )
683 MESSAGE("PARAVIS deactivation ...")
685 QMenu* aMenu = menuMgr()->findMenu( myRecentMenuId );
687 QList<QAction*> anActns = aMenu->actions();
688 for (int i = 0; i < anActns.size(); ++i) {
689 QAction* a = anActns.at(i);
691 a->setVisible(false);
695 QList<QMenu*>::iterator it;
696 for (it = myMenus.begin(); it != myMenus.end(); ++it) {
697 QAction* a = (*it)->menuAction();
699 a->setVisible(false);
702 QList<QDockWidget*> aStreamingViews = application()->desktop()->findChildren<QDockWidget*>("pqStreamingControls");
703 foreach(QDockWidget* aView, aStreamingViews) {
704 if (!myDockWidgets.contains(aView))
705 myDockWidgets[aView] = aView->isVisible();
708 /*if (pqImplementation::helpWindow) {
709 pqImplementation::helpWindow->hide();
713 menuMgr()->hide(myRecentMenuId);
714 menuMgr()->hide(mySourcesMenuId);
715 menuMgr()->hide(myFiltersMenuId);
716 menuMgr()->hide(myMacrosMenuId);
717 menuMgr()->hide(myToolbarsMenuId);
718 setMenuShown( false );
719 setToolShown( false );
721 saveDockWidgetsState();
723 SUIT_ExceptionHandler::removeCleanUpRoutine( paravisCleanUp );
726 qInstallMsgHandler(myOldMsgHandler);
728 restoreCommonWindowsState();
730 return LightApp_Module::deactivateModule( study );
735 \brief Called when application is closed.
737 Process finalize application functionality from ParaView in order to save server settings
738 and nullify application pointer if the application is being closed.
740 \param theApp application
742 void PVGUI_Module::onApplicationClosed( SUIT_Application* theApp )
744 PVViewer_ViewManager::ParaviewCleanup();
746 int aAppsNb = SUIT_Session::session()->applications().size();
748 deleteTemporaryFiles();
750 CAM_Module::onApplicationClosed(theApp);
755 \brief Deletes temporary files created during import operation from VISU
757 void PVGUI_Module::deleteTemporaryFiles()
759 foreach(QString aFile, myTemporaryFiles) {
760 if (QFile::exists(aFile)) {
761 QFile::remove(aFile);
768 \brief Called when study is closed.
770 Removes data model from the \a study.
772 \param study study being closed
774 void PVGUI_Module::studyClosed(SUIT_Study* study)
776 clearParaviewState();
778 LightApp_Module::studyClosed(study);
782 \brief Called when study is opened.
784 void PVGUI_Module::onModelOpened()
786 _PTR(Study) studyDS = PARAVIS::GetCStudy(this);
791 _PTR(SComponent) paravisComp =
792 studyDS->FindComponent(PARAVIS_MODULE_NAME);
797 _PTR(ChildIterator) anIter(studyDS->NewChildIterator(paravisComp));
798 for (; anIter->More(); anIter->Next()) {
799 _PTR(SObject) aSObj = anIter->Value();
800 _PTR(GenericAttribute) anAttr;
801 if (!aSObj->FindAttribute(anAttr, "AttributeLocalID")) {
804 _PTR(AttributeLocalID) anID(anAttr);
805 if (anID->Value() == PVSTATEID) {
812 \brief Returns IOR of current engine
814 QString PVGUI_Module::engineIOR() const
816 CORBA::String_var anIOR = GetCPPEngine()->GetIOR();
817 return QString(anIOR.in());
821 \brief Open file of format supported by ParaView
823 void PVGUI_Module::openFile(const char* theName)
827 pqLoadDataReaction::loadData(aFiles);
831 * \brief Starts Python trace.
833 * Start trace invoking the newly introduced C++ API (PV 4.2)
834 * (inspired from pqTraceReaction::start())
836 void PVGUI_Module::startTrace()
838 vtkSMSessionProxyManager* pxm = pqActiveObjects::instance().activeServer()->proxyManager();
840 vtkSmartPointer<vtkSMProxy> proxy;
841 proxy.TakeReference(pxm->NewProxy("pythontracing", "PythonTraceOptions"));
844 vtkNew<vtkSMParaViewPipelineController> controller;
845 controller->InitializeProxy(proxy);
847 vtkSMTrace* trace = vtkSMTrace::StartTrace();
850 // Set manually the properties entered via the dialog box poping-up when requiring
851 // a trace start in PV4.2 (trace options)
852 trace->SetPropertiesToTraceOnCreate(vtkSMTrace::RECORD_USER_MODIFIED_PROPERTIES);
853 trace->SetFullyTraceSupplementalProxies(false);
858 * \brief Stops Python trace.
860 void PVGUI_Module::stopTrace()
862 vtkSMTrace::StopTrace();
866 * \brief Execute a Python script.
868 void PVGUI_Module::executeScript(const char *script)
871 pqPythonManager* manager = qobject_cast<pqPythonManager*>(
872 pqApplicationCore::instance()->manager("PYTHON_MANAGER"));
874 pqPythonDialog* pyDiag = manager->pythonShellDialog();
876 pyDiag->runString(script);
883 // * Debug function printing out the given interpreter's execution context
885 //void printInterpContext(PyInterp_Interp * interp )
887 // // Extract __smtraceString from interpreter's context
888 // const PyObject* ctxt = interp->getExecutionContext();
890 // PyObject* lst = PyDict_Keys((PyObject *)ctxt);
891 // Py_ssize_t siz = PyList_GET_SIZE(lst);
892 // for (Py_ssize_t i = 0; i < siz; i++)
894 // PyObject * elem = PyList_GetItem(lst, i);
895 // if (PyString_Check(elem))
897 // std::cout << "At pos:" << i << ", " << PyString_AsString(elem) << std::endl;
900 // std::cout << "At pos:" << i << ", not a string!" << std::endl;
906 \brief Returns trace string
908 static const QString MYReplaceStr("paraview.simple");
909 QString PVGUI_Module::getTraceString()
911 vtkSMTrace *tracer = vtkSMTrace::GetActiveTracer();
912 if (!tracer) // trace is not started
915 QString traceString(tracer->GetCurrentTrace());
916 std::stringstream nl; nl << std::endl; // surely there is some Qt trick to do that in a portable way??
917 QString end_line(nl.str().c_str());
918 // 'import pvsimple' is necessary to fix the first call to DisableFirstRenderCamera in the paraview trace
919 // 'ShowParaviewView()' ensure there is an opened viewing window (otherwise SEGFAULT!)
920 traceString = "import pvsimple" + end_line +
921 "pvsimple.ShowParaviewView()" + end_line + traceString;
923 // Replace import "paraview.simple" by "pvsimple"
924 if ((!traceString.isNull()) && traceString.length() != 0) {
925 int aPos = traceString.indexOf(MYReplaceStr);
927 traceString = traceString.replace(aPos, MYReplaceStr.length(), "pvsimple");
928 aPos = traceString.indexOf(MYReplaceStr, aPos);
936 \brief Saves trace string to disk file
938 void PVGUI_Module::saveTrace(const char* theName)
941 if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
942 MESSAGE( "Could not open file:" << theName );
945 QTextStream out(&file);
946 out << getTraceString();
951 \brief Saves ParaView state to a disk file
953 void PVGUI_Module::saveParaviewState(const char* theFileName)
955 pqApplicationCore::instance()->saveState(theFileName);
959 \brief Delete all objects for Paraview Pipeline Browser
961 void PVGUI_Module::clearParaviewState()
963 QAction* deleteAllAction = action(DeleteAllId);
964 if (deleteAllAction) {
965 deleteAllAction->activate(QAction::Trigger);
970 \brief Restores ParaView state from a disk file
972 If toClear == true, the current ojects will be deleted
974 void PVGUI_Module::loadParaviewState(const char* theFileName)
976 pqApplicationCore::instance()->loadState(theFileName, getActiveServer());
980 \brief Returns current active ParaView server
982 pqServer* PVGUI_Module::getActiveServer()
984 return pqApplicationCore::instance()->getActiveServer();
989 \brief Creates PARAVIS preferences panel.
991 void PVGUI_Module::createPreferences()
993 // Paraview settings tab
994 int aParaViewSettingsTab = addPreference( tr( "TIT_PVIEWSETTINGS" ) );
996 setPreferenceProperty(aParaViewSettingsTab, "stretch", false );
997 int aPanel = addPreference(QString(), aParaViewSettingsTab, LightApp_Preferences::UserDefined, PARAVIS_MODULE_NAME, "");
999 setPreferenceProperty(aPanel, "content", (qint64)(new PVGUI_ParaViewSettingsPane(0, getApp())));
1001 // Paravis settings tab
1002 int aParaVisSettingsTab = addPreference( tr( "TIT_PVISSETTINGS" ) );
1003 addPreference( tr( "PREF_STOP_TRACE" ), aParaVisSettingsTab, LightApp_Preferences::Bool, PARAVIS_MODULE_NAME, "stop_trace");
1005 addPreference( tr( "PREF_NO_EXT_PVSERVER" ), aParaVisSettingsTab, LightApp_Preferences::Bool, PARAVIS_MODULE_NAME, "no_ext_pv_server");
1007 int aSaveType = addPreference(tr( "PREF_SAVE_TYPE_LBL" ), aParaVisSettingsTab,
1008 LightApp_Preferences::Selector,
1009 PARAVIS_MODULE_NAME, "savestate_type");
1010 QList<QVariant> aIndices;
1011 QStringList aStrings;
1013 aStrings<<tr("PREF_SAVE_TYPE_0");
1014 aStrings<<tr("PREF_SAVE_TYPE_1");
1015 aStrings<<tr("PREF_SAVE_TYPE_2");
1016 setPreferenceProperty(aSaveType, "strings", aStrings);
1017 setPreferenceProperty(aSaveType, "indexes", aIndices);
1021 \brief Creates ParaViS context menu popup
1023 void PVGUI_Module::contextMenuPopup(const QString& theClient, QMenu* theMenu, QString& theTitle)
1025 LightApp_Module::contextMenuPopup(theClient, theMenu, theTitle);
1027 // Check if we are in Object Browser
1028 SUIT_DataBrowser* ob = getApp()->objectBrowser();
1029 bool isOBClient = (ob && theClient == ob->popupClientType());
1034 // Get list of selected objects
1035 LightApp_SelectionMgr* aSelectionMgr = getApp()->selectionMgr();
1036 SALOME_ListIO aListIO;
1037 aSelectionMgr->selectedObjects(aListIO);
1038 if (aListIO.Extent() == 1 && aListIO.First()->hasEntry()) {
1039 QString entry = QString(aListIO.First()->getEntry());
1042 SalomeApp_Study* activeStudy =
1043 dynamic_cast<SalomeApp_Study*>(getApp()->activeStudy());
1048 // Get SALOMEDS client study
1049 _PTR(Study) studyDS = activeStudy->studyDS();
1054 QString paravisDataType(PARAVIS_MODULE_NAME);
1055 if(activeStudy && activeStudy->isComponent(entry) &&
1056 activeStudy->componentDataType(entry) == paravisDataType) {
1057 // ParaViS module object
1058 theMenu->addSeparator();
1059 theMenu->addAction(action(SaveStatePopupId));
1062 // Try to get state object
1063 _PTR(SObject) stateSObj =
1064 studyDS->FindObjectID(entry.toLatin1().constData());
1070 _PTR(GenericAttribute) anAttr;
1071 if (!stateSObj->FindAttribute(anAttr, "AttributeLocalID")) {
1075 _PTR(AttributeLocalID) anID(anAttr);
1077 if (anID->Value() == PVSTATEID) {
1078 // Paraview state object
1079 theMenu->addSeparator();
1080 theMenu->addAction(action(AddStatePopupId));
1081 theMenu->addAction(action(CleanAndAddStatePopupId));
1082 theMenu->addSeparator();
1083 theMenu->addAction(action(ParaVisRenameId));
1084 theMenu->addAction(action(ParaVisDeleteId));
1091 \brief. Show ParaView python trace.
1093 void PVGUI_Module::onShowTrace()
1095 if (!myTraceWindow) {
1096 myTraceWindow = new pqPythonScriptEditor(getApp()->desktop());
1098 myTraceWindow->setText(getTraceString());
1099 myTraceWindow->show();
1100 myTraceWindow->raise();
1101 myTraceWindow->activateWindow();
1106 \brief. Re-initialize ParaView python trace.
1108 void PVGUI_Module::onRestartTrace()
1115 \brief Save state under the module root object.
1117 void PVGUI_Module::onSaveMultiState()
1119 // Create state study object
1121 // Get SALOMEDS client study
1122 _PTR(Study) studyDS = PARAVIS::GetCStudy(this);
1127 _PTR(SComponent) paravisComp =
1128 studyDS->FindComponent(PARAVIS_MODULE_NAME);
1133 // Unlock the study if it is locked
1134 bool isLocked = studyDS->GetProperties()->IsLocked();
1136 studyDS->GetProperties()->SetLocked(false);
1139 QString stateName = tr("SAVED_PARAVIEW_STATE_NAME") +
1140 QString::number(myStateCounter + 1);
1142 _PTR(StudyBuilder) studyBuilder = studyDS->NewBuilder();
1143 _PTR(SObject) newSObj = studyBuilder->NewObject(paravisComp);
1146 _PTR(GenericAttribute) anAttr;
1147 anAttr = studyBuilder->FindOrCreateAttribute(newSObj, "AttributeName");
1148 _PTR(AttributeName) nameAttr(anAttr);
1150 nameAttr->SetValue(stateName.toLatin1().constData());
1153 anAttr = studyBuilder->FindOrCreateAttribute(newSObj, "AttributeLocalID");
1154 _PTR(AttributeLocalID) localIdAttr(anAttr);
1156 localIdAttr->SetValue(PVSTATEID);
1159 QString stateEntry = QString::fromStdString(newSObj->GetID());
1161 // File name for state saving
1162 QString tmpDir = QString::fromStdString(SALOMEDS_Tool::GetTmpDir());
1163 QString fileName = QString("%1_paravisstate:%2").arg(tmpDir, stateEntry);
1165 anAttr = studyBuilder->FindOrCreateAttribute(newSObj, "AttributeString");
1166 _PTR(AttributeString) stringAttr(anAttr);
1168 stringAttr->SetValue(fileName.toLatin1().constData());
1170 // Lock the study back if necessary
1172 studyDS->GetProperties()->SetLocked(true);
1176 saveParaviewState(fileName.toLatin1().constData());
1177 myTemporaryFiles.append(fileName);
1179 // Increment the counter
1186 \brief Restore the selected state by merging with the current one.
1188 void PVGUI_Module::onAddState()
1190 loadSelectedState(false);
1194 \brief Clean the current state and restore the selected one.
1196 void PVGUI_Module::onCleanAddState()
1198 loadSelectedState(true);
1202 \brief Rename the selected object.
1204 void PVGUI_Module::onRename()
1206 LightApp_SelectionMgr* aSelectionMgr = getApp()->selectionMgr();
1207 SALOME_ListIO aListIO;
1208 aSelectionMgr->selectedObjects(aListIO);
1210 if (aListIO.Extent() == 1 && aListIO.First()->hasEntry()) {
1211 std::string entry = aListIO.First()->getEntry();
1213 // Get SALOMEDS client study
1214 _PTR(Study) studyDS = PARAVIS::GetCStudy(this);
1219 // Unlock the study if it is locked
1220 bool isLocked = studyDS->GetProperties()->IsLocked();
1222 studyDS->GetProperties()->SetLocked(false);
1225 // Rename the selected state object
1226 _PTR(SObject) stateSObj = studyDS->FindObjectID(entry);
1231 _PTR(GenericAttribute) anAttr;
1232 if (stateSObj->FindAttribute(anAttr, "AttributeName")) {
1233 _PTR(AttributeName) nameAttr (anAttr);
1235 LightApp_NameDlg::getName(getApp()->desktop(), nameAttr->Value().c_str());
1236 if (!newName.isEmpty()) {
1237 nameAttr->SetValue(newName.toLatin1().constData());
1238 aListIO.First()->setName(newName.toLatin1().constData());
1242 // Lock the study back if necessary
1244 studyDS->GetProperties()->SetLocked(true);
1247 // Update object browser
1254 \brief Delete the selected objects.
1256 void PVGUI_Module::onDelete()
1258 LightApp_SelectionMgr* aSelectionMgr = getApp()->selectionMgr();
1259 SALOME_ListIO aListIO;
1260 aSelectionMgr->selectedObjects(aListIO);
1262 if (aListIO.Extent() == 1 && aListIO.First()->hasEntry()) {
1263 std::string entry = aListIO.First()->getEntry();
1265 // Get SALOMEDS client study
1266 _PTR(Study) studyDS = PARAVIS::GetCStudy(this);
1271 // Unlock the study if it is locked
1272 bool isLocked = studyDS->GetProperties()->IsLocked();
1274 studyDS->GetProperties()->SetLocked(false);
1277 // Remove the selected state from the study
1278 _PTR(StudyBuilder) studyBuilder = studyDS->NewBuilder();
1279 _PTR(SObject) stateSObj = studyDS->FindObjectID(entry);
1280 studyBuilder->RemoveObject(stateSObj);
1282 // Lock the study back if necessary
1284 studyDS->GetProperties()->SetLocked(true);
1287 // Update object browser
1293 * \brief Slot called everytime the Python trace is pushed onto the CORBA engine.
1295 void PVGUI_Module::onPushTraceTimer()
1297 //MESSAGE("onPushTraceTimer(): Pushing trace to engine...");
1298 GetEngine()->PutPythonTraceStringToEngine(getTraceString().toStdString().c_str());
1302 \brief Discover help project files from the resources.
1303 \return name of the help file.
1305 QString PVGUI_Module::getHelpFileName() {
1306 QString aPVHome(getenv("PVHOME"));
1307 if (aPVHome.isNull()) {
1308 qWarning("Wariable PVHOME is not defined");
1311 QChar aSep = QDir::separator();
1312 //PARAVIEW_VERSION from the vtkPVConfig.h file
1313 QString aFileName = aPVHome + aSep + "share" + aSep + "doc" + aSep + "paraview-"+ PARAVIEW_VERSION + aSep + "paraview.qch";
1319 \brief Load selected paraview state
1321 If toClear == true, the current state will be cleared
1323 void PVGUI_Module::loadSelectedState(bool toClear)
1327 LightApp_SelectionMgr* aSelectionMgr = getApp()->selectionMgr();
1328 SALOME_ListIO aListIO;
1329 aSelectionMgr->selectedObjects(aListIO);
1331 if (aListIO.Extent() == 1 && aListIO.First()->hasEntry()) {
1332 std::string entry = aListIO.First()->getEntry();
1334 // Get SALOMEDS client study
1335 _PTR(Study) studyDS = PARAVIS::GetCStudy(this);
1341 _PTR(SObject) stateSObj = studyDS->FindObjectID(entry);
1342 _PTR(GenericAttribute) anAttr;
1343 if (!stateSObj->FindAttribute(anAttr, "AttributeLocalID")) {
1346 _PTR(AttributeLocalID) anID(anAttr);
1347 if (!anID->Value() == PVSTATEID) {
1351 // Get state file name
1352 if (stateSObj->FindAttribute(anAttr, "AttributeString")) {
1353 _PTR(AttributeString) aStringAttr(anAttr);
1354 QString stringValue(aStringAttr->Value().c_str());
1356 if (QFile::exists(stringValue)) {
1357 fileName = stringValue;
1362 if (!fileName.isEmpty()) {
1364 clearParaviewState();
1367 loadParaviewState(fileName.toLatin1().constData());
1370 SUIT_MessageBox::critical(getApp()->desktop(),
1372 tr("ERR_STATE_CANNOT_BE_RESTORED"));
1377 \fn CAM_Module* createModule();
1378 \brief Export module instance (factory function).
1379 \return new created instance of the module
1383 #define PVGUI_EXPORT __declspec(dllexport)
1385 #define PVGUI_EXPORT
1391 PVGUI_EXPORT CAM_Module* createModule() {
1392 return new PVGUI_Module();
1395 PVGUI_EXPORT char* getModuleVersion() {
1396 return (char*)PARAVIS_VERSION_STR;