1 // PARAVIS : ParaView wrapper SALOME module
3 // Copyright (C) 2010-2014 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 #include <Standard_math.hxx> // E.A. must be included before Python.h to fix compilation on windows
25 #undef HAVE_FINITE // VSR: avoid compilation warning on Linux : "HAVE_FINITE" redefined
27 #include <vtkPython.h> // Python first
28 #include "PVGUI_Module.h"
30 #ifdef PARAVIS_WITH_FULL_CORBA
31 # include "PARAVIS_Gen_i.hh"
34 #include CORBA_SERVER_HEADER(SALOME_ModuleCatalog)
35 #include CORBA_SERVER_HEADER(SALOMEDS)
37 #include "PVGUI_ViewManager.h"
38 #include "PVGUI_ViewWindow.h"
39 #include "PVGUI_ViewModel.h"
40 #include "PVGUI_Tools.h"
41 #include "PVGUI_ParaViewSettingsPane.h"
44 #include <SUIT_DataBrowser.h>
45 #include <SUIT_Desktop.h>
46 #include <SUIT_MessageBox.h>
47 #include <SUIT_ResourceMgr.h>
48 #include <SUIT_Session.h>
49 #include <SUIT_OverrideCursor.h>
50 #include <SUIT_ExceptionHandler.h>
52 #include <SALOME_LifeCycleCORBA.hxx>
53 #include <SALOMEDS_SObject.hxx>
55 #include <LightApp_SelectionMgr.h>
56 #include <LightApp_NameDlg.h>
57 #include <SalomeApp_Application.h>
58 #include <SalomeApp_Study.h>
59 #include <SALOME_ListIO.hxx>
60 #include <SALOMEDS_Tool.hxx>
61 #include <Utils_ORB_INIT.hxx>
62 #include <Utils_SINGLETON.hxx>
64 #include <QtxActionMenuMgr.h>
65 #include <QtxActionToolMgr.h>
67 #include <PARAVIS_version.h>
73 #include <QApplication>
79 #include <QInputDialog>
83 #include <QStringList>
86 #include <QTextStream>
88 #include <QDockWidget>
89 #include <QHelpEngine>
92 #include <vtkPVConfig.h> // for symbol PARAVIEW_VERSION
93 #include <vtkProcessModule.h>
94 #include <vtkPVSession.h>
95 #include <vtkPVProgressHandler.h>
96 #include <vtkOutputWindow.h>
97 #include <vtkEventQtSlotConnect.h>
99 #include <vtkSMProxy.h>
100 #include <vtkSmartPointer.h>
101 #include <vtkSMSession.h>
102 #include <vtkSMTrace.h>
103 #include <vtkSMSessionProxyManager.h>
104 #include <vtkSMParaViewPipelineController.h>
106 #include <pqApplicationCore.h>
107 #include <pqPVApplicationCore.h>
108 #include <pqActiveView.h>
109 #include <pqObjectBuilder.h>
110 #include <pqOptions.h>
111 #include <pqSettings.h>
112 #include <pqServer.h>
113 #include <pqUndoStack.h>
114 #include <pqTabbedMultiViewWidget.h>
115 #include <pqActiveObjects.h>
116 #include <pqHelpReaction.h>
117 #include <pqPluginManager.h>
118 #include <pqPythonDialog.h>
119 #include <pqPythonManager.h>
120 #include <pqLoadDataReaction.h>
121 #include <pqPythonScriptEditor.h>
122 #include <pqDataRepresentation.h>
123 #include <pqDisplayColorWidget.h>
124 #include <pqColorToolbar.h>
125 #include <pqScalarBarVisibilityReaction.h>
126 #include <pqServerResource.h>
127 #include <pqServerConnectReaction.h>
129 //----------------------------------------------------------------------------
130 PVGUI_Module* ParavisModule = 0;
135 <h2>Building and installing PARAVIS</h2>
136 As any other SALOME module, PARAVIS requires PARAVIS_ROOT_DIR environment variable to be set to PARAVIS
137 installation directory.
138 Other variables needed for correct detection of ParaView location:
139 \li PVHOME - points at the ParaView installation directory tree
140 \li PVVERSION - number of ParaView version
142 It also requires common SALOME environment including GUI_ROOT_DIR and other prerequsites.
145 PARAVIS module can be launched using the following commands:
146 \li Full SALOME configuration
148 runSalome --modules="PARAVIS"
151 <h2>ParaView GUI integration</h2>
152 <h3>ParaView GUI integration overview</h3>
154 The main idea is to reuse ParaView GUI internal logic as much as possible, providing a layer
155 between it and SALOME GUI that hides the following SALOME GUI implementation details from ParaView:
157 \li SALOME GUI executable and Qt event loop
158 \li SALOME GUI desktop
159 \li Dock windows areas
160 \li SALOME menu and toolbar managers
162 Major part of the integration is implemented in PVGUI_Module class.
164 <h3>ParaView client initalization</h3>
166 ParaView client initalization is performed when an instance of PVGUI_Module class has been created
167 and \link PVGUI_Module::initialize() PVGUI_Module::initialize()\endlink method is called by SALOME GUI.
168 The actual client start-up is done in \link PVGUI_Module::pvInit() PVGUI_Module::pvInit()\endlink method.
171 <h3>Multi-view manager</h3>
173 SALOME GUI requires that each kind of view be implemnted with help of (at least) three classes. For ParaView multi-view manager
176 \li PVGUI_ViewManager - view manager class
177 \li PVGUI_Viewer - view model class
178 \li PVGUI_ViewWindow - view window class that acts as a parent for %pqViewManager
180 Single instances of PVGUI_ViewManager and PVGUI_ViewWindow classes are created by \link PVGUI_Module::showView()
181 PVGUI_Module::showView()\endlink method upon the first PARAVIS module activation. The same method hides the multi-view manager
182 when the module is deactivated (the user switches to another module or a study is closed).
183 A special trick is used to make PVGUI_ViewWindow the parent of %pqViewManager widget. It is created initally by %pqMainWindowCore
184 with the desktop as a parent, so when it is shown PVGUI_ViewWindow instance is passed to its setParent() method. In
185 \link PVGUI_ViewWindow::~PVGUI_ViewWindow() PVGUI_ViewWindow::~PVGUI_ViewWindow()\endlink the parent is nullified to avoid deletion
186 of %pqViewManager widget that would break %pqMainWindowCore class.
188 <h3>ParaView plugins</h3>
189 ParaView server and client plugins are managed by %pqMainWindowCore slots that has full access to PARAVIS menus and toolbars.
190 As a result they appears automatically in PARAVIS menus and toolbars if loaded successfully.
195 \brief Implementation
196 SALOME module wrapping ParaView GUI.
200 ClientFindOrCreateParavisComponent(_PTR(Study) theStudyDocument)
202 _PTR(SComponent) aSComponent = theStudyDocument->FindComponent("PARAVIS");
204 _PTR(StudyBuilder) aStudyBuilder = theStudyDocument->NewBuilder();
205 aStudyBuilder->NewCommand();
206 int aLocked = theStudyDocument->GetProperties()->IsLocked();
207 if (aLocked) theStudyDocument->GetProperties()->SetLocked(false);
208 aSComponent = aStudyBuilder->NewComponent("PARAVIS");
209 _PTR(GenericAttribute) anAttr =
210 aStudyBuilder->FindOrCreateAttribute(aSComponent, "AttributeName");
211 _PTR(AttributeName) aName (anAttr);
213 ORB_INIT& init = *SINGLETON_<ORB_INIT>::Instance();
214 CORBA::ORB_var anORB = init( qApp->argc(), qApp->argv() );
216 SALOME_NamingService *NamingService = new SALOME_NamingService( anORB );
217 CORBA::Object_var objVarN = NamingService->Resolve("/Kernel/ModulCatalog");
218 SALOME_ModuleCatalog::ModuleCatalog_var Catalogue =
219 SALOME_ModuleCatalog::ModuleCatalog::_narrow(objVarN);
220 SALOME_ModuleCatalog::Acomponent_var Comp = Catalogue->GetComponent( "PARAVIS" );
221 if (!Comp->_is_nil()) {
222 aName->SetValue(Comp->componentusername());
225 anAttr = aStudyBuilder->FindOrCreateAttribute(aSComponent, "AttributePixMap");
226 _PTR(AttributePixMap) aPixmap (anAttr);
227 aPixmap->SetPixMap( "pqAppIcon16.png" );
229 // Create Attribute parameters for future using
230 anAttr = aStudyBuilder->FindOrCreateAttribute(aSComponent, "AttributeParameter");
232 aStudyBuilder->DefineComponentInstance(aSComponent, PVGUI_Module::GetEngine()->GetIOR());
233 if (aLocked) theStudyDocument->GetProperties()->SetLocked(true);
234 aStudyBuilder->CommitCommand();
240 Clean up function; used to stop ParaView progress events when
241 exception is caught by global exception handler.
243 void paravisCleanUp()
245 if ( pqApplicationCore::instance() ) {
246 pqServer* s = pqApplicationCore::instance()->getActiveServer();
247 if ( s ) s->session()->GetProgressHandler()->CleanupPendingProgress();
252 \brief Constructor. Sets the default name for the module.
254 PVGUI_Module::PVGUI_Module()
255 : SalomeApp_Module( "PARAVIS" ),
256 mySelectionControlsTb( -1 ),
257 mySourcesMenuId( -1 ),
258 myFiltersMenuId( -1 ),
260 myToolbarsMenuId(-1),
269 Q_INIT_RESOURCE( PVGUI );
271 ParavisModule = this;
273 // Clear old copies of embedded macros files
274 QString aDestPath = QString( "%1/.config/%2/Macros" ).arg( QDir::homePath() ).arg( QApplication::applicationName() );
278 QDir aDestDir(aDestPath);
279 QStringList aDestFiles = aDestDir.entryList(aFilter, QDir::Files);
280 foreach (QString aMacrosPath, getEmbeddedMacrosList()) {
281 QString aMacrosName = QFileInfo(aMacrosPath).fileName();
282 if (aDestFiles.contains(aMacrosName)) {
283 aDestDir.remove(aMacrosName);
291 PVGUI_Module::~PVGUI_Module()
293 if (myPushTraceTimer)
294 delete myPushTraceTimer;
299 PARAVIS_ORB::PARAVIS_Gen_var PVGUI_Module::GetEngine()
301 return PVGUI_ViewManager::GetEngine();
304 pqPVApplicationCore * PVGUI_Module::GetPVApplication()
306 return PVGUI_ViewManager::GetPVApplication();
310 \brief Initialize module. Creates menus, prepares context menu, etc.
311 \param app SALOME GUI application instance
313 void PVGUI_Module::initialize( CAM_Application* app )
315 SalomeApp_Module::initialize( app );
317 // Create ParaViS actions
319 // Create ParaViS menus
322 // Uncomment to debug ParaView initialization
323 // "aa" used instead of "i" as GDB doesn't like "i" variables :)
331 SalomeApp_Application* anApp = getApp();
332 SUIT_Desktop* aDesktop = anApp->desktop();
334 // Initialize ParaView client and associated behaviors
335 // and connect to externally launched pvserver
336 PVGUI_ViewManager::ParaviewInitApp(aDesktop);
338 // Remember current state of desktop toolbars
339 QList<QToolBar*> foreignToolbars = aDesktop->findChildren<QToolBar*>();
343 // Behaviors and connection must be instanciated *after* widgets are in place:
344 PVGUI_ViewManager::ParaviewInitBehaviors(true, aDesktop);
345 PVGUI_ViewManager::ConnectToExternalPVServer(aDesktop);
351 QList<QDockWidget*> activeDocks = aDesktop->findChildren<QDockWidget*>();
352 QList<QMenu*> activeMenus = aDesktop->findChildren<QMenu*>();
354 // Setup quick-launch shortcuts.
355 QShortcut *ctrlSpace = new QShortcut(Qt::CTRL + Qt::Key_Space, aDesktop);
356 QObject::connect(ctrlSpace, SIGNAL(activated()),
357 pqApplicationCore::instance(), SLOT(quickLaunch()));
359 // Find Plugin Dock Widgets
360 QList<QDockWidget*> currentDocks = aDesktop->findChildren<QDockWidget*>();
361 QList<QDockWidget*>::iterator i;
362 for (i = currentDocks.begin(); i != currentDocks.end(); ++i) {
363 if(!activeDocks.contains(*i)) {
364 myDockWidgets[*i] = false; // hidden by default
370 // [ABN] TODO: fix this - triggers a SEGFAULT at deactivation() time.
371 // QList<QMenu*> currentMenus = aDesktop->findChildren<QMenu*>();
372 // QList<QMenu*>::iterator im;
373 // for (im = currentMenus.begin(); im != currentMenus.end(); ++im) {
374 // if(!activeMenus.contains(*im)) {
375 // QString s = (*im)->title();
376 // std::cout << " MENU "<< s.toStdString() << std::endl;
377 // myMenus.append(*im);
381 SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
382 QString aPath = resMgr->stringValue("resources", "PARAVIS", QString());
383 if (!aPath.isNull()) {
384 pqPVApplicationCore * pvApp = GetPVApplication();
385 pvApp->loadConfiguration(aPath + QDir::separator() + "ParaViewFilters.xml");
386 pvApp->loadConfiguration(aPath + QDir::separator() + "ParaViewReaders.xml");
387 pvApp->loadConfiguration(aPath + QDir::separator() + "ParaViewSources.xml");
388 pvApp->loadConfiguration(aPath + QDir::separator() + "ParaViewWriters.xml");
393 // Find created toolbars
394 QCoreApplication::processEvents();
396 QList<QToolBar*> allToolbars = aDesktop->findChildren<QToolBar*>();
397 foreach(QToolBar* aBar, allToolbars) {
398 if (!foreignToolbars.contains(aBar)) {
399 myToolbars[aBar] = true;
400 myToolbarBreaks[aBar] = false;
401 aBar->setVisible(false);
402 aBar->toggleViewAction()->setVisible(false);
408 SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr();
409 bool isStop = aResourceMgr->booleanValue( "PARAVIS", "stop_trace", false );
412 // Start a timer to schedule asap:
413 // - the connection to the server
415 myInitTimer = new QTimer(aDesktop);
416 QObject::connect(myInitTimer, SIGNAL(timeout()), this, SLOT(onInitTimer()) );
417 myInitTimer->setSingleShot(true);
418 myInitTimer->start(0);
420 // Another timer to regularly push the trace onto the engine:
421 myPushTraceTimer = new QTimer(aDesktop);
422 QObject::connect(myPushTraceTimer, SIGNAL(timeout()), this, SLOT(onPushTraceTimer()) );
423 myPushTraceTimer->setSingleShot(false);
424 myPushTraceTimer->start(500);
427 this->VTKConnect = vtkEventQtSlotConnect::New();
429 vtkProcessModule* pm = vtkProcessModule::GetProcessModule();
431 vtkPVSession* pvs = dynamic_cast<vtkPVSession*>(pm->GetSession());
433 vtkPVProgressHandler* ph = pvs->GetProgressHandler();
435 this->VTKConnect->Connect(ph, vtkCommand::StartEvent,
436 this, SLOT(onStartProgress()));
437 this->VTKConnect->Connect(ph, vtkCommand::EndEvent,
438 this, SLOT(onEndProgress()));
444 void PVGUI_Module::onStartProgress()
446 QApplication::setOverrideCursor(Qt::WaitCursor);
449 void PVGUI_Module::onEndProgress()
451 QApplication::restoreOverrideCursor();
454 void PVGUI_Module::onDataRepresentationUpdated() {
455 SalomeApp_Study* activeStudy = dynamic_cast<SalomeApp_Study*>(application()->activeStudy());
456 if(!activeStudy) return;
458 activeStudy->Modified();
462 \brief Initialisation timer event - fired only once, after the GUI loop is ready.
463 See creation in initialize().
465 void PVGUI_Module::onInitTimer()
467 #ifndef PARAVIS_WITH_FULL_CORBA
468 // connectToExternalPVServer();
474 \brief Get list of embedded macros files
476 QStringList PVGUI_Module::getEmbeddedMacrosList()
478 QString aRootDir = getenv("PARAVIS_ROOT_DIR");
480 QString aSourcePath = aRootDir + "/bin/salome/Macro";
485 QDir aSourceDir(aSourcePath);
486 QStringList aSourceFiles = aSourceDir.entryList(aFilter, QDir::Files);
487 QStringList aFullPathSourceFiles;
488 foreach (QString aMacrosName, aSourceFiles) {
489 aFullPathSourceFiles << aSourceDir.absoluteFilePath(aMacrosName);
491 return aFullPathSourceFiles;
494 void PVGUI_Module::updateMacros()
496 pqPythonManager* aPythonManager = pqPVApplicationCore::instance()->pythonManager();
497 if(!aPythonManager) {
501 foreach (QString aStr, getEmbeddedMacrosList()) {
502 aPythonManager->addMacro(aStr);
508 \brief Get list of compliant dockable GUI elements
509 \param m map to be filled in ("type":"default_position")
511 void PVGUI_Module::windows( QMap<int, int>& m ) const
513 m.insert( LightApp_Application::WT_ObjectBrowser, Qt::LeftDockWidgetArea );
514 m.insert( LightApp_Application::WT_PyConsole, Qt::BottomDockWidgetArea );
515 // ParaView diagnostic output redirected here
516 m.insert( LightApp_Application::WT_LogWindow, Qt::BottomDockWidgetArea );
520 \brief Shows (toShow = true) or hides ParaView view window
522 void PVGUI_Module::showView( bool toShow )
524 SalomeApp_Application* anApp = getApp();
525 PVGUI_ViewManager* viewMgr =
526 dynamic_cast<PVGUI_ViewManager*>( anApp->getViewManager( PVGUI_Viewer::Type(), false ) );
528 viewMgr = new PVGUI_ViewManager( anApp->activeStudy(), anApp->desktop() );
529 anApp->addViewManager( viewMgr );
530 connect( viewMgr, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
531 anApp, SLOT( onCloseView( SUIT_ViewManager* ) ) );
534 PVGUI_ViewWindow* pvWnd = dynamic_cast<PVGUI_ViewWindow*>( viewMgr->getActiveView() );
536 pvWnd = dynamic_cast<PVGUI_ViewWindow*>( viewMgr->createViewWindow() );
539 pvWnd->setShown( toShow );
540 if ( toShow ) pvWnd->setFocus();
544 \brief Slot to show help for proxy.
546 void PVGUI_Module::showHelpForProxy( const QString& groupname, const QString& proxyname )
548 pqHelpReaction::showProxyHelp(groupname, proxyname);
553 \brief Slot to show the waiting state.
555 void PVGUI_Module::onPreAccept()
557 getApp()->desktop()->statusBar()->showMessage(tr("STB_PREACCEPT"));
558 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
562 \brief Slot to show the ready state.
564 void PVGUI_Module::onPostAccept()
566 getApp()->desktop()->statusBar()->showMessage(tr("STB_POSTACCEPT"), 2000);
567 QTimer::singleShot(0, this, SLOT(endWaitCursor()));
571 \brief Slot to switch off wait cursor.
573 void PVGUI_Module::endWaitCursor()
575 QApplication::restoreOverrideCursor();
578 static void ParavisMessageOutput(QtMsgType type, const char *msg)
583 vtkOutputWindow::GetInstance()->DisplayText(msg);
586 vtkOutputWindow::GetInstance()->DisplayErrorText(msg);
589 vtkOutputWindow::GetInstance()->DisplayErrorText(msg);
592 vtkOutputWindow::GetInstance()->DisplayErrorText(msg);
598 \brief Activate module.
599 \param study current study
600 \return \c true if activaion is done successfully or 0 to prevent
603 bool PVGUI_Module::activateModule( SUIT_Study* study )
605 myOldMsgHandler = qInstallMsgHandler(ParavisMessageOutput);
607 SUIT_ExceptionHandler::addCleanUpRoutine( paravisCleanUp );
609 storeCommonWindowsState();
611 bool isDone = SalomeApp_Module::activateModule( study );
612 if ( !isDone ) return false;
615 if ( mySourcesMenuId != -1 ) menuMgr()->show(mySourcesMenuId);
616 if ( myFiltersMenuId != -1 ) menuMgr()->show(myFiltersMenuId);
617 if ( myFiltersMenuId != -1 ) menuMgr()->show(myMacrosMenuId);
618 if ( myFiltersMenuId != -1 ) menuMgr()->show(myToolbarsMenuId);
619 setMenuShown( true );
620 setToolShown( true );
622 restoreDockWidgetsState();
624 QMenu* aMenu = menuMgr()->findMenu( myRecentMenuId );
626 QList<QAction*> anActns = aMenu->actions();
627 for (int i = 0; i < anActns.size(); ++i) {
628 QAction* a = anActns.at(i);
634 QList<QMenu*>::iterator it;
635 for (it = myMenus.begin(); it != myMenus.end(); ++it) {
636 QAction* a = (*it)->menuAction();
641 if ( myRecentMenuId != -1 ) menuMgr()->show(myRecentMenuId);
643 ClientFindOrCreateParavisComponent(PARAVIS::GetCStudy(this));
650 \brief Deactivate module.
651 \param study current study
652 \return \c true if deactivaion is done successfully or 0 to prevent
653 deactivation on error
655 bool PVGUI_Module::deactivateModule( SUIT_Study* study )
657 MESSAGE("PARAVIS deactivation ...")
659 QMenu* aMenu = menuMgr()->findMenu( myRecentMenuId );
661 QList<QAction*> anActns = aMenu->actions();
662 for (int i = 0; i < anActns.size(); ++i) {
663 QAction* a = anActns.at(i);
665 a->setVisible(false);
669 QList<QMenu*>::iterator it;
670 for (it = myMenus.begin(); it != myMenus.end(); ++it) {
671 QAction* a = (*it)->menuAction();
673 a->setVisible(false);
676 QList<QDockWidget*> aStreamingViews = application()->desktop()->findChildren<QDockWidget*>("pqStreamingControls");
677 foreach(QDockWidget* aView, aStreamingViews) {
678 if (!myDockWidgets.contains(aView))
679 myDockWidgets[aView] = aView->isVisible();
682 /*if (pqImplementation::helpWindow) {
683 pqImplementation::helpWindow->hide();
687 menuMgr()->hide(myRecentMenuId);
688 menuMgr()->hide(mySourcesMenuId);
689 menuMgr()->hide(myFiltersMenuId);
690 menuMgr()->hide(myMacrosMenuId);
691 menuMgr()->hide(myToolbarsMenuId);
692 setMenuShown( false );
693 setToolShown( false );
695 saveDockWidgetsState();
697 SUIT_ExceptionHandler::removeCleanUpRoutine( paravisCleanUp );
700 qInstallMsgHandler(myOldMsgHandler);
702 restoreCommonWindowsState();
704 return SalomeApp_Module::deactivateModule( study );
709 \brief Called when application is closed.
711 Process finalize application functionality from ParaView in order to save server settings
712 and nullify application pointer if the application is being closed.
714 \param theApp application
716 void PVGUI_Module::onApplicationClosed( SUIT_Application* theApp )
718 PVGUI_ViewManager::ParaviewCleanup();
720 int aAppsNb = SUIT_Session::session()->applications().size();
722 deleteTemporaryFiles();
724 CAM_Module::onApplicationClosed(theApp);
729 \brief Deletes temporary files created during import operation from VISU
731 void PVGUI_Module::deleteTemporaryFiles()
733 foreach(QString aFile, myTemporaryFiles) {
734 if (QFile::exists(aFile)) {
735 QFile::remove(aFile);
742 \brief Called when study is closed.
744 Removes data model from the \a study.
746 \param study study being closed
748 void PVGUI_Module::studyClosed(SUIT_Study* study)
750 clearParaviewState();
752 SalomeApp_Module::studyClosed(study);
756 \brief Called when study is opened.
758 void PVGUI_Module::onModelOpened()
760 _PTR(Study) studyDS = PARAVIS::GetCStudy(this);
765 _PTR(SComponent) paravisComp =
766 studyDS->FindComponent(GetEngine()->ComponentDataType());
771 _PTR(ChildIterator) anIter(studyDS->NewChildIterator(paravisComp));
772 for (; anIter->More(); anIter->Next()) {
773 _PTR(SObject) aSObj = anIter->Value();
774 _PTR(GenericAttribute) anAttr;
775 if (!aSObj->FindAttribute(anAttr, "AttributeLocalID")) {
778 _PTR(AttributeLocalID) anID(anAttr);
779 if (anID->Value() == PVSTATEID) {
786 \brief Returns IOR of current engine
788 QString PVGUI_Module::engineIOR() const
790 CORBA::String_var anIOR = GetEngine()->GetIOR();
791 return QString(anIOR.in());
795 \brief Open file of format supported by ParaView
797 void PVGUI_Module::openFile(const char* theName)
801 pqLoadDataReaction::loadData(aFiles);
805 * Start trace invoking the newly introduced C++ API (PV 4.2)
806 * (inspired from pqTraceReaction::start())
808 void PVGUI_Module::startTrace()
810 vtkSMSessionProxyManager* pxm = pqActiveObjects::instance().activeServer()->proxyManager();
812 vtkSmartPointer<vtkSMProxy> proxy;
813 proxy.TakeReference(pxm->NewProxy("pythontracing", "PythonTraceOptions"));
816 vtkNew<vtkSMParaViewPipelineController> controller;
817 controller->InitializeProxy(proxy);
819 vtkSMTrace* trace = vtkSMTrace::StartTrace();
822 // Set manually the properties entered via the dialog box poping-up when requiring
823 // a trace start in PV4.2 (trace options)
824 trace->SetPropertiesToTraceOnCreate(vtkSMTrace::RECORD_USER_MODIFIED_PROPERTIES);
825 trace->SetFullyTraceSupplementalProxies(false);
829 void PVGUI_Module::stopTrace()
831 vtkSMTrace::StopTrace();
834 void PVGUI_Module::executeScript(const char *script)
837 pqPythonManager* manager = qobject_cast<pqPythonManager*>(
838 pqApplicationCore::instance()->manager("PYTHON_MANAGER"));
840 pqPythonDialog* pyDiag = manager->pythonShellDialog();
842 pyDiag->runString(script);
849 // * Debug function printing out the given interpreter's execution context
851 //void printInterpContext(PyInterp_Interp * interp )
853 // // Extract __smtraceString from interpreter's context
854 // const PyObject* ctxt = interp->getExecutionContext();
856 // PyObject* lst = PyDict_Keys((PyObject *)ctxt);
857 // Py_ssize_t siz = PyList_GET_SIZE(lst);
858 // for (Py_ssize_t i = 0; i < siz; i++)
860 // PyObject * elem = PyList_GetItem(lst, i);
861 // if (PyString_Check(elem))
863 // std::cout << "At pos:" << i << ", " << PyString_AsString(elem) << std::endl;
866 // std::cout << "At pos:" << i << ", not a string!" << std::endl;
872 \brief Returns trace string
874 static const QString MYReplaceStr("paraview.simple");
875 static const QString MYReplaceImportStr("except: from pvsimple import *");
876 QString PVGUI_Module::getTraceString()
878 vtkSMTrace *tracer = vtkSMTrace::GetActiveTracer();
879 if (!tracer) // trace is not started
882 QString traceString(tracer->GetCurrentTrace());
884 // Replace import "paraview.simple" by "pvsimple"
885 if ((!traceString.isNull()) && traceString.length() != 0) {
886 int aPos = traceString.indexOf(MYReplaceStr);
888 traceString = traceString.replace(aPos, MYReplaceStr.length(), "pvsimple");
889 aPos = traceString.indexOf(MYReplaceStr, aPos);
891 int aImportPos = traceString.indexOf(MYReplaceImportStr);
894 traceString = traceString.replace(aImportPos, MYReplaceImportStr.length(), "except:\n import pvsimple\n from pvsimple import *");
902 \brief Saves trace string to disk file
904 void PVGUI_Module::saveTrace(const char* theName)
907 if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
908 MESSAGE( "Could not open file:" << theName );
911 QTextStream out(&file);
912 out << getTraceString();
917 \brief Saves ParaView state to a disk file
919 void PVGUI_Module::saveParaviewState(const char* theFileName)
921 pqApplicationCore::instance()->saveState(theFileName);
925 \brief Delete all objects for Paraview Pipeline Browser
927 void PVGUI_Module::clearParaviewState()
929 QAction* deleteAllAction = action(DeleteAllId);
930 if (deleteAllAction) {
931 deleteAllAction->activate(QAction::Trigger);
936 \brief Restores ParaView state from a disk file
938 If toClear == true, the current ojects will be deleted
940 void PVGUI_Module::loadParaviewState(const char* theFileName)
942 pqApplicationCore::instance()->loadState(theFileName, getActiveServer());
946 \brief Returns current active ParaView server
948 pqServer* PVGUI_Module::getActiveServer()
950 return pqApplicationCore::instance()->getActiveServer();
955 \brief Creates PARAVIS preference pane
957 void PVGUI_Module::createPreferences()
959 // Paraview settings tab
960 int aParaViewSettingsTab = addPreference( tr( "TIT_PVIEWSETTINGS" ) );
961 int aPanel = addPreference(QString(), aParaViewSettingsTab, LightApp_Preferences::UserDefined, "PARAVIS", "");
962 setPreferenceProperty(aPanel, "content", (qint64)(new PVGUI_ParaViewSettingsPane()));
964 // Paravis settings tab
965 int aParaVisSettingsTab = addPreference( tr( "TIT_PVISSETTINGS" ) );
966 addPreference( tr( "PREF_STOP_TRACE" ), aParaVisSettingsTab, LightApp_Preferences::Bool, "PARAVIS", "stop_trace");
968 int aSaveType = addPreference(tr( "PREF_SAVE_TYPE_LBL" ), aParaVisSettingsTab,
969 LightApp_Preferences::Selector,
970 "PARAVIS", "savestate_type");
971 QList<QVariant> aIndices;
972 QStringList aStrings;
974 aStrings<<tr("PREF_SAVE_TYPE_0");
975 aStrings<<tr("PREF_SAVE_TYPE_1");
976 aStrings<<tr("PREF_SAVE_TYPE_2");
977 setPreferenceProperty(aSaveType, "strings", aStrings);
978 setPreferenceProperty(aSaveType, "indexes", aIndices);
982 \brief Creates ParaViS context menu popup
984 void PVGUI_Module::contextMenuPopup(const QString& theClient, QMenu* theMenu, QString& theTitle)
986 SalomeApp_Module::contextMenuPopup(theClient, theMenu, theTitle);
988 // Check if we are in Object Browser
989 SUIT_DataBrowser* ob = getApp()->objectBrowser();
990 bool isOBClient = (ob && theClient == ob->popupClientType());
995 // Get list of selected objects
996 LightApp_SelectionMgr* aSelectionMgr = getApp()->selectionMgr();
997 SALOME_ListIO aListIO;
998 aSelectionMgr->selectedObjects(aListIO);
999 if (aListIO.Extent() == 1 && aListIO.First()->hasEntry()) {
1000 QString entry = QString(aListIO.First()->getEntry());
1003 SalomeApp_Study* activeStudy =
1004 dynamic_cast<SalomeApp_Study*>(getApp()->activeStudy());
1009 // Get SALOMEDS client study
1010 _PTR(Study) studyDS = activeStudy->studyDS();
1015 QString paravisDataType(GetEngine()->ComponentDataType());
1016 if(activeStudy && activeStudy->isComponent(entry) &&
1017 activeStudy->componentDataType(entry) == paravisDataType) {
1018 // ParaViS module object
1019 theMenu->addSeparator();
1020 theMenu->addAction(action(SaveStatePopupId));
1023 // Try to get state object
1024 _PTR(SObject) stateSObj =
1025 studyDS->FindObjectID(entry.toLatin1().constData());
1031 _PTR(GenericAttribute) anAttr;
1032 if (!stateSObj->FindAttribute(anAttr, "AttributeLocalID")) {
1036 _PTR(AttributeLocalID) anID(anAttr);
1038 if (anID->Value() == PVSTATEID) {
1039 // Paraview state object
1040 theMenu->addSeparator();
1041 theMenu->addAction(action(AddStatePopupId));
1042 theMenu->addAction(action(CleanAndAddStatePopupId));
1043 theMenu->addSeparator();
1044 theMenu->addAction(action(ParaVisRenameId));
1045 theMenu->addAction(action(ParaVisDeleteId));
1052 \brief. Show ParaView python trace.
1054 void PVGUI_Module::onShowTrace()
1056 if (!myTraceWindow) {
1057 myTraceWindow = new pqPythonScriptEditor(getApp()->desktop());
1059 myTraceWindow->setText(getTraceString());
1060 myTraceWindow->show();
1061 myTraceWindow->raise();
1062 myTraceWindow->activateWindow();
1067 \brief. Re-initialize ParaView python trace.
1069 void PVGUI_Module::onRestartTrace()
1076 \brief Show ParaView view.
1078 void PVGUI_Module::onNewParaViewWindow()
1084 \brief Save state under the module root object.
1086 void PVGUI_Module::onSaveMultiState()
1088 // Create state study object
1090 // Get SALOMEDS client study
1091 _PTR(Study) studyDS = PARAVIS::GetCStudy(this);
1096 _PTR(SComponent) paravisComp =
1097 studyDS->FindComponent(GetEngine()->ComponentDataType());
1102 // Unlock the study if it is locked
1103 bool isLocked = studyDS->GetProperties()->IsLocked();
1105 studyDS->GetProperties()->SetLocked(false);
1108 QString stateName = tr("SAVED_PARAVIEW_STATE_NAME") +
1109 QString::number(myStateCounter + 1);
1111 _PTR(StudyBuilder) studyBuilder = studyDS->NewBuilder();
1112 _PTR(SObject) newSObj = studyBuilder->NewObject(paravisComp);
1115 _PTR(GenericAttribute) anAttr;
1116 anAttr = studyBuilder->FindOrCreateAttribute(newSObj, "AttributeName");
1117 _PTR(AttributeName) nameAttr(anAttr);
1119 nameAttr->SetValue(stateName.toLatin1().constData());
1122 anAttr = studyBuilder->FindOrCreateAttribute(newSObj, "AttributeLocalID");
1123 _PTR(AttributeLocalID) localIdAttr(anAttr);
1125 localIdAttr->SetValue(PVSTATEID);
1128 QString stateEntry = QString::fromStdString(newSObj->GetID());
1130 // File name for state saving
1131 QString tmpDir = QString::fromStdString(SALOMEDS_Tool::GetTmpDir());
1132 QString fileName = QString("%1_paravisstate:%2").arg(tmpDir, stateEntry);
1134 anAttr = studyBuilder->FindOrCreateAttribute(newSObj, "AttributeString");
1135 _PTR(AttributeString) stringAttr(anAttr);
1137 stringAttr->SetValue(fileName.toLatin1().constData());
1139 // Lock the study back if necessary
1141 studyDS->GetProperties()->SetLocked(true);
1145 saveParaviewState(fileName.toLatin1().constData());
1146 myTemporaryFiles.append(fileName);
1148 // Increment the counter
1155 \brief Restore the selected state by merging with the current one.
1157 void PVGUI_Module::onAddState()
1159 loadSelectedState(false);
1163 \brief Clean the current state and restore the selected one.
1165 void PVGUI_Module::onCleanAddState()
1167 loadSelectedState(true);
1171 \brief Rename the selected object.
1173 void PVGUI_Module::onRename()
1175 LightApp_SelectionMgr* aSelectionMgr = getApp()->selectionMgr();
1176 SALOME_ListIO aListIO;
1177 aSelectionMgr->selectedObjects(aListIO);
1179 if (aListIO.Extent() == 1 && aListIO.First()->hasEntry()) {
1180 std::string entry = aListIO.First()->getEntry();
1182 // Get SALOMEDS client study
1183 _PTR(Study) studyDS = PARAVIS::GetCStudy(this);
1188 // Unlock the study if it is locked
1189 bool isLocked = studyDS->GetProperties()->IsLocked();
1191 studyDS->GetProperties()->SetLocked(false);
1194 // Rename the selected state object
1195 _PTR(SObject) stateSObj = studyDS->FindObjectID(entry);
1200 _PTR(GenericAttribute) anAttr;
1201 if (stateSObj->FindAttribute(anAttr, "AttributeName")) {
1202 _PTR(AttributeName) nameAttr (anAttr);
1204 LightApp_NameDlg::getName(getApp()->desktop(), nameAttr->Value().c_str());
1205 if (!newName.isEmpty()) {
1206 nameAttr->SetValue(newName.toLatin1().constData());
1207 aListIO.First()->setName(newName.toLatin1().constData());
1211 // Lock the study back if necessary
1213 studyDS->GetProperties()->SetLocked(true);
1216 // Update object browser
1223 \brief Delete the selected objects.
1225 void PVGUI_Module::onDelete()
1227 LightApp_SelectionMgr* aSelectionMgr = getApp()->selectionMgr();
1228 SALOME_ListIO aListIO;
1229 aSelectionMgr->selectedObjects(aListIO);
1231 if (aListIO.Extent() == 1 && aListIO.First()->hasEntry()) {
1232 std::string entry = aListIO.First()->getEntry();
1234 // Get SALOMEDS client study
1235 _PTR(Study) studyDS = PARAVIS::GetCStudy(this);
1240 // Unlock the study if it is locked
1241 bool isLocked = studyDS->GetProperties()->IsLocked();
1243 studyDS->GetProperties()->SetLocked(false);
1246 // Remove the selected state from the study
1247 _PTR(StudyBuilder) studyBuilder = studyDS->NewBuilder();
1248 _PTR(SObject) stateSObj = studyDS->FindObjectID(entry);
1249 studyBuilder->RemoveObject(stateSObj);
1251 // Lock the study back if necessary
1253 studyDS->GetProperties()->SetLocked(true);
1256 // Update object browser
1261 void PVGUI_Module::onPushTraceTimer()
1263 // MESSAGE("onPushTraceTimer(): Pushing trace to engine...");
1264 GetEngine()->PutPythonTraceStringToEngine(getTraceString().toStdString().c_str());
1268 \brief Discover help project files from the resources.
1269 \return name of the help file.
1271 QString PVGUI_Module::getHelpFileName() {
1272 QString aPVHome(getenv("PVHOME"));
1273 if (aPVHome.isNull()) {
1274 qWarning("Wariable PVHOME is not defined");
1277 QChar aSep = QDir::separator();
1278 //PARAVIEW_VERSION from the vtkPVConfig.h file
1279 QString aFileName = aPVHome + aSep + "share" + aSep + "doc" + aSep + "paraview-"+ PARAVIEW_VERSION + aSep + "paraview.qch";
1285 \brief Load selected paraview state
1287 If toClear == true, the current state will be cleared
1289 void PVGUI_Module::loadSelectedState(bool toClear)
1293 LightApp_SelectionMgr* aSelectionMgr = getApp()->selectionMgr();
1294 SALOME_ListIO aListIO;
1295 aSelectionMgr->selectedObjects(aListIO);
1297 if (aListIO.Extent() == 1 && aListIO.First()->hasEntry()) {
1298 std::string entry = aListIO.First()->getEntry();
1300 // Get SALOMEDS client study
1301 _PTR(Study) studyDS = PARAVIS::GetCStudy(this);
1307 _PTR(SObject) stateSObj = studyDS->FindObjectID(entry);
1308 _PTR(GenericAttribute) anAttr;
1309 if (!stateSObj->FindAttribute(anAttr, "AttributeLocalID")) {
1312 _PTR(AttributeLocalID) anID(anAttr);
1313 if (!anID->Value() == PVSTATEID) {
1317 // Get state file name
1318 if (stateSObj->FindAttribute(anAttr, "AttributeString")) {
1319 _PTR(AttributeString) aStringAttr(anAttr);
1320 QString stringValue(aStringAttr->Value().c_str());
1322 if (QFile::exists(stringValue)) {
1323 fileName = stringValue;
1328 if (!fileName.isEmpty()) {
1330 clearParaviewState();
1333 loadParaviewState(fileName.toLatin1().constData());
1336 SUIT_MessageBox::critical(getApp()->desktop(),
1338 tr("ERR_STATE_CANNOT_BE_RESTORED"));
1343 \fn CAM_Module* createModule();
1344 \brief Export module instance (factory function).
1345 \return new created instance of the module
1349 #define PVGUI_EXPORT __declspec(dllexport)
1351 #define PVGUI_EXPORT
1357 PVGUI_EXPORT CAM_Module* createModule() {
1358 return new PVGUI_Module();
1361 PVGUI_EXPORT char* getModuleVersion() {
1362 return (char*)PARAVIS_VERSION_STR;