1 // PARAVIS : ParaView wrapper SALOME module
3 // Copyright (C) 2010-2016 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
31 #include "PVGUI_Module.h"
33 #include "PVViewer_ViewManager.h"
34 #include "PVViewer_Core.h"
35 #include "PVViewer_ViewWindow.h"
36 #include "PVViewer_ViewModel.h"
37 #include "PVGUI_ParaViewSettingsPane.h"
38 #include "PVViewer_GUIElements.h"
39 #include "PVServer_ServiceWrapper.h"
40 #include "PVGUI_DataModel.h"
43 #include <utilities.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 <LightApp_SelectionMgr.h>
53 #include <LightApp_NameDlg.h>
54 #include <LightApp_Application.h>
55 #include <LightApp_Study.h>
56 #include <SALOME_ListIO.hxx>
58 #include <QtxActionMenuMgr.h>
59 #include <QtxActionToolMgr.h>
61 #include <PARAVIS_version.h>
67 #include <QApplication>
73 #include <QInputDialog>
77 #include <QStringList>
80 #include <QTextStream>
82 #include <QDockWidget>
83 #include <QHelpEngine>
86 #include <vtkPVConfig.h> // for symbol PARAVIEW_VERSION
87 #include <vtkProcessModule.h>
88 #include <vtkPVSession.h>
89 #include <vtkPVProgressHandler.h>
90 #include <vtkOutputWindow.h>
91 #include <vtkEventQtSlotConnect.h>
93 #include <vtkSMProxy.h>
94 #include <vtkSmartPointer.h>
95 #include <vtkSMSession.h>
96 #include <vtkSMTrace.h>
97 #include <vtkSMSessionProxyManager.h>
98 #include <vtkSMParaViewPipelineController.h>
99 #include <vtkSmartPyObject.h>
101 #include <pqApplicationCore.h>
102 #include <pqPVApplicationCore.h>
103 #include <pqObjectBuilder.h>
104 #include <pqOptions.h>
105 #include <pqSettings.h>
106 #include <pqServer.h>
107 #include <pqUndoStack.h>
108 #include <pqTabbedMultiViewWidget.h>
109 #include <pqActiveObjects.h>
110 #include <pqHelpReaction.h>
111 #include <pqPluginManager.h>
112 #include <pqPythonDialog.h>
113 #include <pqPythonManager.h>
114 #include <pqLoadDataReaction.h>
115 #include <pqPythonScriptEditor.h>
116 #include <pqDataRepresentation.h>
117 #include <pqDisplayColorWidget.h>
118 #include <pqColorToolbar.h>
119 #include <pqScalarBarVisibilityReaction.h>
120 #include <pqServerResource.h>
121 #include <pqServerConnectReaction.h>
122 #include <pqPluginManager.h>
123 #include <pqVCRToolbar.h>
124 #include <pqAnimationScene.h>
125 #include <pqServerManagerModel.h>
126 #include <pqAnimationTimeToolbar.h>
128 //----------------------------------------------------------------------------
129 PVGUI_Module* ParavisModule = 0;
133 This is the doxygen documentation of the ParaVis module.
134 If you are looking for general information about the structure of the module, you should
135 take a look at the <a href="../index.html">Sphinx documentation</a> first.
137 The integration of ParaView into SALOME is split in two parts:
138 \li the PVViewer in the GUI module (folder *src/PVViewer*)
139 \li the ParaVis module itself (the pages you are currently browsing)
144 \brief Implementation
145 SALOME module wrapping ParaView GUI.
149 \brief Clean up function
151 Used to stop ParaView progress events when
152 exception is caught by global exception handler.
154 void paravisCleanUp()
156 if ( pqApplicationCore::instance() ) {
157 pqServer* s = pqApplicationCore::instance()->getActiveServer();
158 if ( s ) s->session()->GetProgressHandler()->CleanupPendingProgress();
163 \brief Constructor. Sets the default name for the module.
165 PVGUI_Module::PVGUI_Module()
166 : LightApp_Module( PARAVIS_MODULE_NAME ),
167 mySourcesMenuId( -1 ),
168 myFiltersMenuId( -1 ),
171 myCatalystMenuId(-1),
178 Q_INIT_RESOURCE( PVGUI );
180 ParavisModule = this;
182 // Clear old copies of embedded macros files
183 QString aDestPath = QString( "%1/.config/%2/Macros" ).arg( QDir::homePath() ).arg( QApplication::applicationName() );
187 QDir aDestDir(aDestPath);
188 QStringList aDestFiles = aDestDir.entryList(aFilter, QDir::Files);
189 foreach (QString aMacrosPath, getEmbeddedMacrosList()) {
190 QString aMacrosName = QFileInfo(aMacrosPath).fileName();
191 if (aDestFiles.contains(aMacrosName)) {
192 aDestDir.remove(aMacrosName);
200 PVGUI_Module::~PVGUI_Module()
207 \brief Retrieve the PVSERVER CORBA engine.
208 This uses the Python wrapper provided
209 by the PVViewer code in GUI (class PVViewer_EngineWrapper).
212 PVServer_ServiceWrapper* PVGUI_Module::GetEngine()
214 return PVServer_ServiceWrapper::GetInstance();
218 \brief Create data model.
219 \return module specific data model
221 CAM_DataModel* PVGUI_Module::createDataModel()
223 return new PVGUI_DataModel( this );
227 \brief Get the ParaView application singleton.
229 pqPVApplicationCore* PVGUI_Module::GetPVApplication()
231 return PVViewer_Core::GetPVApplication();
235 \brief Initialize module. Creates menus, prepares context menu, etc.
236 \param app SALOME GUI application instance
238 void PVGUI_Module::initialize( CAM_Application* app )
240 LightApp_Module::initialize( app );
242 // Uncomment to debug ParaView initialization
243 // "aa" used instead of "i" as GDB doesn't like "i" variables :)
251 LightApp_Application* anApp = getApp();
252 SUIT_Desktop* aDesktop = anApp->desktop();
254 // Remember current state of desktop toolbars
255 QList<QToolBar*> foreignToolbars = aDesktop->findChildren<QToolBar*>();
257 // Initialize ParaView client and associated behaviors
258 // and connect to externally launched pvserver
259 PVViewer_Core::ParaviewInitApp(aDesktop, anApp->logWindow());
260 myGuiElements = PVViewer_GUIElements::GetInstance(aDesktop);
262 // [ABN]: careful with the order of the GUI element creation, the loading of the configuration
263 // and the connection to the server. This order is very sensitive if one wants to make
264 // sure all menus, etc ... are correctly populated.
265 // Reference points are: ParaViewMainWindow.cxx and branded_paraview_initializer.cxx.in
272 PVViewer_Core::ParaviewInitBehaviors(true, aDesktop);
274 QList<QDockWidget*> activeDocks = aDesktop->findChildren<QDockWidget*>();
275 QList<QMenu*> activeMenus = aDesktop->findChildren<QMenu*>();
277 // Setup quick-launch shortcuts.
278 QShortcut *ctrlSpace = new QShortcut(Qt::CTRL + Qt::Key_Space, aDesktop);
279 QObject::connect(ctrlSpace, SIGNAL(activated()),
280 pqApplicationCore::instance(), SLOT(quickLaunch()));
282 // Find Plugin Dock Widgets
283 QList<QDockWidget*> currentDocks = aDesktop->findChildren<QDockWidget*>();
284 QList<QDockWidget*>::iterator i;
285 for (i = currentDocks.begin(); i != currentDocks.end(); ++i) {
286 if(!activeDocks.contains(*i)) {
287 myDockWidgets[*i] = false; // hidden by default
293 // [ABN] TODO: fix this - triggers a SEGFAULT at deactivation() time.
294 // QList<QMenu*> currentMenus = aDesktop->findChildren<QMenu*>();
295 // QList<QMenu*>::iterator im;
296 // for (im = currentMenus.begin(); im != currentMenus.end(); ++im) {
297 // if(!activeMenus.contains(*im)) {
298 // QString s = (*im)->title();
299 // std::cout << " MENU "<< s.toStdString() << std::endl;
300 // myMenus.append(*im);
304 // Connect after toolbar creation, etc ... as some activations of the toolbars is triggered
305 // by the ServerConnection event:
306 const QString configPath(PVViewer_ViewManager::GetPVConfigPath());
307 PVViewer_Core::ParaviewLoadConfigurations(configPath, true);
308 PVViewer_ViewManager::ConnectToExternalPVServer(aDesktop);
311 // Find created toolbars
312 QCoreApplication::processEvents();
314 // process PVViewer toolbars (might be added by PVViewer created BEFORE activating ParaVis)
315 QList<QToolBar*> pvToolbars = myGuiElements->getToolbars();
316 foreach(QToolBar* aBar, pvToolbars) {
317 if (!myToolbars.contains(aBar)) {
318 myToolbars[aBar] = true;
319 myToolbarBreaks[aBar] = false;
320 aBar->setVisible(false);
321 aBar->toggleViewAction()->setVisible(false);
325 // process other toolbars (possibly added by Paraview)
326 QList<QToolBar*> allToolbars = aDesktop->findChildren<QToolBar*>();
327 foreach(QToolBar* aBar, allToolbars) {
328 if (!foreignToolbars.contains(aBar) && !myToolbars.contains(aBar)) {
329 myToolbars[aBar] = true;
330 myToolbarBreaks[aBar] = false;
331 aBar->setVisible(false);
332 aBar->toggleViewAction()->setVisible(false);
338 SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr();
339 bool isStop = aResourceMgr->booleanValue( PARAVIS_MODULE_NAME, "stop_trace", false );
342 // Start a timer to schedule asap:
344 myInitTimer = new QTimer(aDesktop);
345 QObject::connect(myInitTimer, SIGNAL(timeout()), this, SLOT(onInitTimer()) );
346 myInitTimer->setSingleShot(true);
347 myInitTimer->start(0);
350 this->VTKConnect = vtkEventQtSlotConnect::New();
352 vtkProcessModule* pm = vtkProcessModule::GetProcessModule();
354 vtkPVSession* pvs = dynamic_cast<vtkPVSession*>(pm->GetSession());
356 vtkPVProgressHandler* ph = pvs->GetProgressHandler();
358 this->VTKConnect->Connect(ph, vtkCommand::StartEvent,
359 this, SLOT(onStartProgress()));
360 this->VTKConnect->Connect(ph, vtkCommand::EndEvent,
361 this, SLOT(onEndProgress()));
365 connect( application(), SIGNAL( appClosed() ), this, SLOT( onStopTrace() ) );
369 * \brief Slot called when the progress bar starts.
371 void PVGUI_Module::onStartProgress()
373 // VSR 19/03/2015, issue 0023025
374 // next line is commented: it is bad idea to show wait cursor on ANY vtk event
375 // moreover, it does not work when running pvserver with --multi-client mode
376 //QApplication::setOverrideCursor(Qt::WaitCursor);
380 * \brief Slot called when the progress bar is done.
382 void PVGUI_Module::onEndProgress()
384 // VSR 19/03/2015, issue 0023025
385 // next line is commented: it is bad idea to show wait cursor on ANY vtk event
386 // moreover, it does not work when running pvserver with --multi-client mode
387 //QApplication::restoreOverrideCursor();
390 void PVGUI_Module::onDataRepresentationUpdated() {
391 LightApp_Study* activeStudy = dynamic_cast<LightApp_Study*>(application()->activeStudy());
392 if(!activeStudy) return;
394 activeStudy->Modified();
398 \brief Initialisation timer event - Starts up the Python trace
400 void PVGUI_Module::onInitTimer()
406 \brief Get list of embedded macros files
408 QStringList PVGUI_Module::getEmbeddedMacrosList()
410 QString aRootDir = getenv("PARAVIS_ROOT_DIR");
412 QString aSourcePath = aRootDir + "/bin/salome/Macro";
417 QDir aSourceDir(aSourcePath);
418 QStringList aSourceFiles = aSourceDir.entryList(aFilter, QDir::Files);
419 QStringList aFullPathSourceFiles;
420 foreach (QString aMacrosName, aSourceFiles) {
421 aFullPathSourceFiles << aSourceDir.absoluteFilePath(aMacrosName);
423 return aFullPathSourceFiles;
427 \brief Update the list of embedded macros
429 void PVGUI_Module::updateMacros()
431 pqPythonManager* aPythonManager = pqPVApplicationCore::instance()->pythonManager();
432 if(!aPythonManager) {
436 foreach (QString aStr, getEmbeddedMacrosList()) {
437 aPythonManager->addMacro(aStr);
443 \brief Get list of compliant dockable GUI elements
444 \param m map to be filled in ("type":"default_position")
446 void PVGUI_Module::windows( QMap<int, int>& m ) const
448 m.insert( LightApp_Application::WT_ObjectBrowser, Qt::LeftDockWidgetArea );
449 #ifndef DISABLE_PYCONSOLE
450 m.insert( LightApp_Application::WT_PyConsole, Qt::BottomDockWidgetArea );
452 // ParaView diagnostic output redirected here
453 m.insert( LightApp_Application::WT_LogWindow, Qt::BottomDockWidgetArea );
457 \brief Shows (toShow = true) or hides ParaView view window
459 void PVGUI_Module::showView( bool toShow )
461 // VSR: TODO: all below is not needed, if we use standard approach
462 // that consists in implementing viewManagers() function properly
463 // This should be done after we decide what to do with Log window.
464 LightApp_Application* anApp = getApp();
465 PVViewer_ViewManager* viewMgr =
466 dynamic_cast<PVViewer_ViewManager*>( anApp->getViewManager( PVViewer_Viewer::Type(), false ) );
468 viewMgr = new PVViewer_ViewManager( anApp->activeStudy(), anApp->desktop(), anApp->logWindow() );
469 anApp->addViewManager( viewMgr );
470 connect( viewMgr, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
471 anApp, SLOT( onCloseView( SUIT_ViewManager* ) ) );
474 PVViewer_ViewWindow* pvWnd = dynamic_cast<PVViewer_ViewWindow*>( viewMgr->getActiveView() );
476 pvWnd = dynamic_cast<PVViewer_ViewWindow*>( viewMgr->createViewWindow() );
477 // this also connects to the pvserver and instantiates relevant PV behaviors
480 pvWnd->setVisible( toShow );
481 if ( toShow ) pvWnd->setFocus();
485 \brief Slot to show help for proxy.
487 void PVGUI_Module::showHelpForProxy( const QString& groupname, const QString& proxyname )
489 pqHelpReaction::showProxyHelp(groupname, proxyname);
493 \brief Slot to show the waiting state.
495 void PVGUI_Module::onPreAccept()
497 getApp()->desktop()->statusBar()->showMessage(tr("STB_PREACCEPT"));
498 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
502 \brief Slot to show the ready state.
504 void PVGUI_Module::onPostAccept()
506 getApp()->desktop()->statusBar()->showMessage(tr("STB_POSTACCEPT"), 2000);
507 QTimer::singleShot(0, this, SLOT(endWaitCursor()));
511 \brief Slot to switch off wait cursor.
513 void PVGUI_Module::endWaitCursor()
515 QApplication::restoreOverrideCursor();
517 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
519 \brief Handler method for the output of messages.
521 static void ParavisMessageOutput(QtMsgType type, const char *msg)
526 vtkOutputWindow::GetInstance()->DisplayText(msg);
529 vtkOutputWindow::GetInstance()->DisplayErrorText(msg);
532 vtkOutputWindow::GetInstance()->DisplayErrorText(msg);
535 vtkOutputWindow::GetInstance()->DisplayErrorText(msg);
541 \brief Handler method for the output of messages.
543 static void ParavisMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
548 vtkOutputWindow::GetInstance()->DisplayText(msg.toLatin1().constData());
551 vtkOutputWindow::GetInstance()->DisplayErrorText(msg.toLatin1().constData());
554 vtkOutputWindow::GetInstance()->DisplayErrorText(msg.toLatin1().constData());
557 vtkOutputWindow::GetInstance()->DisplayErrorText(msg.toLatin1().constData());
563 \brief Activate module.
564 \param study current study
565 \return \c true if activaion is done successfully or 0 to prevent
568 bool PVGUI_Module::activateModule( SUIT_Study* study )
570 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
571 myOldMsgHandler = qInstallMsgHandler(ParavisMessageOutput);
573 myOldMsgHandler = qInstallMessageHandler(ParavisMessageOutput);
575 SUIT_ExceptionHandler::addCleanUpRoutine( paravisCleanUp );
577 storeCommonWindowsState();
579 bool isDone = LightApp_Module::activateModule( study );
580 if ( !isDone ) return false;
583 if ( mySourcesMenuId != -1 ) menuMgr()->show(mySourcesMenuId);
584 if ( myFiltersMenuId != -1 ) menuMgr()->show(myFiltersMenuId);
585 if ( myMacrosMenuId != -1 ) menuMgr()->show(myMacrosMenuId);
586 if ( myCatalystMenuId != -1 ) menuMgr()->show(myCatalystMenuId);
588 // Update the various menus with the content pre-loaded in myGuiElements
589 // QMenu* srcMenu = menuMgr()->findMenu( mySourcesMenuId );
590 // myGuiElements->updateSourcesMenu(srcMenu);
591 // QMenu* filtMenu = menuMgr()->findMenu( myFiltersMenuId );
592 // myGuiElements->updateFiltersMenu(filtMenu);
593 // QMenu* macMenu = menuMgr()->findMenu( myMacrosMenuId );
594 // myGuiElements->updateMacrosMenu(macMenu);
596 setMenuShown( true );
597 setToolShown( true );
599 restoreDockWidgetsState();
601 QMenu* aMenu = menuMgr()->findMenu( myRecentMenuId );
603 QList<QAction*> anActns = aMenu->actions();
604 for (int i = 0; i < anActns.size(); ++i) {
605 QAction* a = anActns.at(i);
611 QList<QMenu*>::iterator it;
612 for (it = myMenus.begin(); it != myMenus.end(); ++it) {
613 QAction* a = (*it)->menuAction();
618 if ( myRecentMenuId != -1 ) menuMgr()->show(myRecentMenuId);
625 \brief Deactivate module.
626 \param study current study
627 \return \c true if deactivaion is done successfully or 0 to prevent
628 deactivation on error
630 bool PVGUI_Module::deactivateModule( SUIT_Study* study )
632 MESSAGE("PARAVIS deactivation ...")
634 QMenu* aMenu = menuMgr()->findMenu( myRecentMenuId );
636 QList<QAction*> anActns = aMenu->actions();
637 for (int i = 0; i < anActns.size(); ++i) {
638 QAction* a = anActns.at(i);
640 a->setVisible(false);
644 QList<QMenu*>::iterator it;
645 for (it = myMenus.begin(); it != myMenus.end(); ++it) {
646 QAction* a = (*it)->menuAction();
648 a->setVisible(false);
651 QList<QDockWidget*> aStreamingViews = application()->desktop()->findChildren<QDockWidget*>("pqStreamingControls");
652 foreach(QDockWidget* aView, aStreamingViews) {
653 if (!myDockWidgets.contains(aView))
654 myDockWidgets[aView] = aView->isVisible();
657 /*if (pqImplementation::helpWindow) {
658 pqImplementation::helpWindow->hide();
661 menuMgr()->hide(myRecentMenuId);
662 menuMgr()->hide(mySourcesMenuId);
663 menuMgr()->hide(myFiltersMenuId);
664 menuMgr()->hide(myMacrosMenuId);
665 menuMgr()->hide(myCatalystMenuId);
666 setMenuShown( false );
667 setToolShown( false );
669 saveDockWidgetsState();
671 SUIT_ExceptionHandler::removeCleanUpRoutine( paravisCleanUp );
674 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
675 qInstallMsgHandler(myOldMsgHandler);
677 qInstallMessageHandler(myOldMsgHandler);
679 restoreCommonWindowsState();
681 return LightApp_Module::deactivateModule( study );
686 \brief Called when application is closed.
688 Process finalize application functionality from ParaView in order to save server settings
689 and nullify application pointer if the application is being closed.
691 \param theApp application
693 void PVGUI_Module::onApplicationClosed( SUIT_Application* theApp )
695 PVViewer_Core::ParaviewCleanup();
696 CAM_Module::onApplicationClosed(theApp);
700 \brief Called when study is closed.
702 Removes data model from the \a study.
704 \param study study being closed
706 void PVGUI_Module::studyClosed(SUIT_Study* study)
708 showView(false); // VSR: this seems to be not needed (all views are automatically closed)
709 clearParaviewState();
713 LightApp_Module::studyClosed(study);
717 \brief Open file of format supported by ParaView
719 void PVGUI_Module::openFile( const char* theName )
723 pqLoadDataReaction::loadData( aFiles );
727 \brief Starts Python trace.
729 Start trace invoking the newly introduced C++ API (PV 4.2)
730 (inspired from pqTraceReaction::start())
732 void PVGUI_Module::startTrace()
734 vtkSMSessionProxyManager* pxm = pqActiveObjects::instance().activeServer()->proxyManager();
736 vtkSmartPointer<vtkSMProxy> proxy;
737 proxy.TakeReference( pxm->NewProxy( "pythontracing", "PythonTraceOptions" ) );
739 vtkNew<vtkSMParaViewPipelineController> controller;
740 controller->InitializeProxy( proxy );
742 vtkSMTrace* trace = vtkSMTrace::StartTrace();
744 // Set manually the properties entered via the dialog box poping-up when requiring
745 // a trace start in PV4.2 (trace options)
746 SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr();
747 int type = aResourceMgr->integerValue( PARAVIS_MODULE_NAME, "tracestate_type", 2 );
748 trace->SetPropertiesToTraceOnCreate( type );
749 trace->SetFullyTraceSupplementalProxies( false );
754 \brief Stops Python trace.
756 void PVGUI_Module::stopTrace()
758 vtkSMTrace::StopTrace();
762 \brief Execute a Python script.
764 void PVGUI_Module::executeScript( const char* script )
767 pqPythonManager* manager = qobject_cast<pqPythonManager*>(
768 pqApplicationCore::instance()->manager( "PYTHON_MANAGER" ) );
770 pqPythonDialog* pyDiag = manager->pythonShellDialog();
772 pyDiag->runString(script);
779 // * Debug function printing out the given interpreter's execution context
781 //void printInterpContext(PyInterp_Interp * interp )
783 // // Extract __smtraceString from interpreter's context
784 // const PyObject* ctxt = interp->getExecutionContext();
786 // PyObject* lst = PyDict_Keys((PyObject *)ctxt);
787 // Py_ssize_t siz = PyList_GET_SIZE(lst);
788 // for (Py_ssize_t i = 0; i < siz; i++)
790 // PyObject * elem = PyList_GetItem(lst, i);
791 // if (PyString_Check(elem))
793 // std::cout << "At pos:" << i << ", " << PyString_AsString(elem) << std::endl;
796 // std::cout << "At pos:" << i << ", not a string!" << std::endl;
802 \brief Returns trace string
804 QString PVGUI_Module::getTraceString()
806 QString traceString = "";
808 static const QString replaceStr( "paraview.simple" );
809 std::stringstream nl;
810 nl << std::endl; // surely there is some Qt trick to do that in a portable way??
811 QString end_line( nl.str().c_str() );
813 vtkSMTrace* tracer = vtkSMTrace::GetActiveTracer();
815 traceString = tracer->GetCurrentTrace();
816 // 'import pvsimple' is necessary to fix the first call to DisableFirstRenderCamera in the paraview trace
817 // 'ShowParaviewView()' ensure there is an opened viewing window (otherwise SEGFAULT!)
818 traceString = "import pvsimple" + end_line +
819 "pvsimple.ShowParaviewView()" + end_line + traceString;
821 // Replace import "paraview.simple" by "pvsimple"
822 if ( !traceString.isEmpty() ) {
823 int aPos = traceString.indexOf( replaceStr );
824 while ( aPos != -1 ) {
825 traceString = traceString.replace( aPos, replaceStr.length(), "pvsimple" );
826 aPos = traceString.indexOf( replaceStr, aPos );
831 // Save camera position to, which is no longer output by the tracer ...
833 vtkPythonScopeGilEnsurer psge;
834 PyObject * mods(PySys_GetObject(const_cast<char*>("modules")));
835 PyObject * trace_mod(PyDict_GetItemString(mods, "paraview.smtrace")); // module was already (really) imported by vtkSMTrace
836 if (PyModule_Check(trace_mod)) {
837 vtkSmartPyObject save_cam(PyObject_GetAttrString(trace_mod, const_cast<char*>("SaveCameras")));
838 vtkSmartPyObject camera_trace(PyObject_CallMethod(save_cam, const_cast<char*>("get_trace"), NULL));
839 // Convert to a single string
840 vtkSmartPyObject ret(PyString_FromString(end_line.toStdString().c_str()));
841 vtkSmartPyObject final_string(PyObject_CallMethod(ret, const_cast<char*>("join"),
842 const_cast<char*>("O"), (PyObject*)camera_trace));
843 if (PyString_CheckExact(final_string))
845 QString camera_qs(PyString_AsString(final_string)); // deep copy
846 traceString = traceString + end_line + end_line + QString("#### saving camera placements for all active views")
847 + end_line + end_line + camera_qs + end_line;
856 \brief Saves trace string to disk file
858 void PVGUI_Module::saveTrace( const char* theName )
860 QFile file( theName );
861 if ( !file.open( QIODevice::WriteOnly | QIODevice::Text ) ) {
862 MESSAGE( "Could not open file:" << theName );
865 QTextStream out( &file );
866 out << getTraceString();
871 \brief Saves ParaView state to a disk file
873 void PVGUI_Module::saveParaviewState( const QString& theFileName )
875 pqApplicationCore::instance()->saveState( theFileName.toStdString().c_str() );
879 \brief Delete all objects for Paraview Pipeline Browser
881 void PVGUI_Module::clearParaviewState()
883 QAction* deleteAllAction = action( DeleteAllId );
884 if ( deleteAllAction ) {
885 deleteAllAction->activate( QAction::Trigger );
890 \brief Restores ParaView state from a disk file
892 void PVGUI_Module::loadParaviewState( const QString& theFileName )
894 pqApplicationCore::instance()->loadState( theFileName.toStdString().c_str(), getActiveServer() );
898 \brief Returns current active ParaView server
900 pqServer* PVGUI_Module::getActiveServer()
902 return pqApplicationCore::instance()->getActiveServer();
907 \brief Creates PARAVIS preferences panel.
909 void PVGUI_Module::createPreferences()
911 QList<QVariant> aIndices;
912 QStringList aStrings;
914 // Paraview settings tab
915 int aParaViewSettingsTab = addPreference( tr( "TIT_PVIEWSETTINGS" ) );
917 setPreferenceProperty(aParaViewSettingsTab, "stretch", false );
918 int aPanel = addPreference( QString(), aParaViewSettingsTab,
919 LightApp_Preferences::UserDefined, PARAVIS_MODULE_NAME, "" );
921 setPreferenceProperty( aPanel, "content", (qint64)( new PVGUI_ParaViewSettingsPane( 0, getApp() ) ) );
923 // Paravis settings tab
924 int aParaVisSettingsTab = addPreference( tr( "TIT_PVISSETTINGS" ) );
926 addPreference( tr( "PREF_NO_EXT_PVSERVER" ), aParaVisSettingsTab,
927 LightApp_Preferences::Bool, PARAVIS_MODULE_NAME, "no_ext_pv_server" );
929 int aSaveType = addPreference( tr( "PREF_SAVE_TYPE_LBL" ), aParaVisSettingsTab,
930 LightApp_Preferences::Selector,
931 PARAVIS_MODULE_NAME, "savestate_type" );
935 aIndices << 0 << 1 << 2;
936 aStrings << tr("PREF_SAVE_TYPE_0") << tr("PREF_SAVE_TYPE_1") << tr("PREF_SAVE_TYPE_2");
937 setPreferenceProperty( aSaveType, "strings", aStrings );
938 setPreferenceProperty( aSaveType, "indexes", aIndices );
940 // ... "Language" group <<start>>
941 int traceGroup = addPreference( tr( "PREF_GROUP_TRACE" ), aParaVisSettingsTab );
943 int stopTrace = addPreference( tr( "PREF_STOP_TRACE" ), traceGroup,
944 LightApp_Preferences::Bool, PARAVIS_MODULE_NAME, "stop_trace" );
945 setPreferenceProperty( stopTrace, "restart", true );
947 int aTraceType = addPreference( tr( "PREF_TRACE_TYPE_LBL" ), traceGroup,
948 LightApp_Preferences::Selector,
949 PARAVIS_MODULE_NAME, "tracestate_type" );
952 aIndices << 0 << 1 << 2;
953 aStrings << tr("PREF_TRACE_TYPE_0") << tr("PREF_TRACE_TYPE_1") << tr("PREF_TRACE_TYPE_2");
954 setPreferenceProperty( aTraceType, "strings", aStrings );
955 setPreferenceProperty( aTraceType, "indexes", aIndices );
956 setPreferenceProperty( aTraceType, "restart", true );
960 \brief. Show ParaView python trace.
962 void PVGUI_Module::onShowTrace()
964 if (!myTraceWindow) {
965 myTraceWindow = new pqPythonScriptEditor(getApp()->desktop());
967 myTraceWindow->setText(getTraceString());
968 myTraceWindow->show();
969 myTraceWindow->raise();
970 myTraceWindow->activateWindow();
975 \brief. Re-initialize ParaView python trace.
977 void PVGUI_Module::onRestartTrace()
984 \brief. Close ParaView python trace.
986 void PVGUI_Module::onStopTrace()
991 \brief Called when view manager is added
993 void PVGUI_Module::onViewManagerAdded( SUIT_ViewManager* vm )
995 if ( PVViewer_ViewManager* pvvm = dynamic_cast<PVViewer_ViewManager*>( vm ) ) {
996 connect( pvvm, SIGNAL( viewCreated( SUIT_ViewWindow* ) ),
997 this, SLOT( onPVViewCreated( SUIT_ViewWindow* ) ) );
998 connect( pvvm, SIGNAL( deleteView( SUIT_ViewWindow* ) ),
999 this, SLOT( onPVViewDelete( SUIT_ViewWindow* ) ) );
1004 \brief Called when view manager is removed
1006 void PVGUI_Module::onViewManagerRemoved( SUIT_ViewManager* vm )
1008 if ( PVViewer_ViewManager* pvvm = dynamic_cast<PVViewer_ViewManager*>( vm ) )
1009 disconnect( pvvm, SIGNAL( viewCreated( SUIT_ViewWindow* ) ),
1010 this, SLOT( onPVViewCreated( SUIT_ViewWindow* ) ) );
1014 \brief Show toolbars at \a vw PV view window creating when PARAVIS is active.
1016 void PVGUI_Module::onPVViewCreated( SUIT_ViewWindow* vw )
1018 myGuiElements->setToolBarVisible( true );
1019 restoreDockWidgetsState();
1023 \brief Save toolbars state at \a view view closing.
1025 void PVGUI_Module::onPVViewDelete( SUIT_ViewWindow* view )
1027 if ( dynamic_cast<PVViewer_ViewWindow*>( view ) )
1028 saveDockWidgetsState( false );
1032 \fn CAM_Module* createModule();
1033 \brief Export module instance (factory function).
1034 \return new created instance of the module
1038 #define PVGUI_EXPORT __declspec(dllexport)
1040 #define PVGUI_EXPORT
1046 PVGUI_EXPORT CAM_Module* createModule() {
1047 return new PVGUI_Module();
1050 PVGUI_EXPORT char* getModuleVersion() {
1051 return (char*)PARAVIS_VERSION_STR;