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 #if PY_VERSION_HEX < 0x03050000
130 Py_EncodeLocale(const wchar_t *arg, size_t *size)
132 return _Py_wchar2char(arg, size);
135 Py_DecodeLocale(const char *arg, size_t *size)
137 return _Py_char2wchar(arg, size);
141 //----------------------------------------------------------------------------
142 PVGUI_Module* ParavisModule = 0;
146 This is the doxygen documentation of the ParaVis module.
147 If you are looking for general information about the structure of the module, you should
148 take a look at the <a href="../index.html">Sphinx documentation</a> first.
150 The integration of ParaView into SALOME is split in two parts:
151 \li the PVViewer in the GUI module (folder *src/PVViewer*)
152 \li the ParaVis module itself (the pages you are currently browsing)
157 \brief Implementation
158 SALOME module wrapping ParaView GUI.
162 \brief Clean up function
164 Used to stop ParaView progress events when
165 exception is caught by global exception handler.
167 void paravisCleanUp()
169 if ( pqApplicationCore::instance() ) {
170 pqServer* s = pqApplicationCore::instance()->getActiveServer();
171 if ( s ) s->session()->GetProgressHandler()->CleanupPendingProgress();
176 \brief Constructor. Sets the default name for the module.
178 PVGUI_Module::PVGUI_Module()
179 : LightApp_Module( PARAVIS_MODULE_NAME ),
180 mySourcesMenuId( -1 ),
181 myFiltersMenuId( -1 ),
190 Q_INIT_RESOURCE( PVGUI );
192 ParavisModule = this;
194 // Clear old copies of embedded macros files
195 QString aDestPath = QString( "%1/.config/%2/Macros" ).arg( QDir::homePath() ).arg( QApplication::applicationName() );
199 QDir aDestDir(aDestPath);
200 QStringList aDestFiles = aDestDir.entryList(aFilter, QDir::Files);
201 foreach (QString aMacrosPath, getEmbeddedMacrosList()) {
202 QString aMacrosName = QFileInfo(aMacrosPath).fileName();
203 if (aDestFiles.contains(aMacrosName)) {
204 aDestDir.remove(aMacrosName);
212 PVGUI_Module::~PVGUI_Module()
219 \brief Retrieve the PVSERVER CORBA engine.
220 This uses the Python wrapper provided
221 by the PVViewer code in GUI (class PVViewer_EngineWrapper).
224 PVServer_ServiceWrapper* PVGUI_Module::GetEngine()
226 return PVServer_ServiceWrapper::GetInstance();
230 \brief Create data model.
231 \return module specific data model
233 CAM_DataModel* PVGUI_Module::createDataModel()
235 return new PVGUI_DataModel( this );
239 \brief Get the ParaView application singleton.
241 pqPVApplicationCore* PVGUI_Module::GetPVApplication()
243 return PVViewer_Core::GetPVApplication();
247 \brief Initialize module. Creates menus, prepares context menu, etc.
248 \param app SALOME GUI application instance
250 void PVGUI_Module::initialize( CAM_Application* app )
252 LightApp_Module::initialize( app );
254 // Uncomment to debug ParaView initialization
255 // "aa" used instead of "i" as GDB doesn't like "i" variables :)
263 LightApp_Application* anApp = getApp();
264 SUIT_Desktop* aDesktop = anApp->desktop();
266 // Remember current state of desktop toolbars
267 QList<QToolBar*> foreignToolbars = aDesktop->findChildren<QToolBar*>();
269 // Initialize ParaView client and associated behaviors
270 // and connect to externally launched pvserver
271 PVViewer_Core::ParaviewInitApp(aDesktop, anApp->logWindow());
272 myGuiElements = PVViewer_GUIElements::GetInstance(aDesktop);
274 // [ABN]: careful with the order of the GUI element creation, the loading of the configuration
275 // and the connection to the server. This order is very sensitive if one wants to make
276 // sure all menus, etc ... are correctly populated.
277 // Reference points are: ParaViewMainWindow.cxx and branded_paraview_initializer.cxx.in
284 PVViewer_Core::ParaviewInitBehaviors(true, aDesktop);
286 QList<QDockWidget*> activeDocks = aDesktop->findChildren<QDockWidget*>();
287 QList<QMenu*> activeMenus = aDesktop->findChildren<QMenu*>();
289 // Setup quick-launch shortcuts.
290 QShortcut *ctrlSpace = new QShortcut(Qt::CTRL + Qt::Key_Space, aDesktop);
291 QObject::connect(ctrlSpace, SIGNAL(activated()),
292 pqApplicationCore::instance(), SLOT(quickLaunch()));
294 // Find Plugin Dock Widgets
295 QList<QDockWidget*> currentDocks = aDesktop->findChildren<QDockWidget*>();
296 QList<QDockWidget*>::iterator i;
297 for (i = currentDocks.begin(); i != currentDocks.end(); ++i) {
298 if(!activeDocks.contains(*i)) {
299 myDockWidgets[*i] = false; // hidden by default
305 // [ABN] TODO: fix this - triggers a SEGFAULT at deactivation() time.
306 // QList<QMenu*> currentMenus = aDesktop->findChildren<QMenu*>();
307 // QList<QMenu*>::iterator im;
308 // for (im = currentMenus.begin(); im != currentMenus.end(); ++im) {
309 // if(!activeMenus.contains(*im)) {
310 // QString s = (*im)->title();
311 // std::cout << " MENU "<< s.toStdString() << std::endl;
312 // myMenus.append(*im);
316 // Connect after toolbar creation, etc ... as some activations of the toolbars is triggered
317 // by the ServerConnection event:
318 const QString configPath(PVViewer_ViewManager::GetPVConfigPath());
319 PVViewer_Core::ParaviewLoadConfigurations(configPath, true);
320 PVViewer_ViewManager::ConnectToExternalPVServer(aDesktop);
323 // Find created toolbars
324 QCoreApplication::processEvents();
326 // process PVViewer toolbars (might be added by PVViewer created BEFORE activating ParaVis)
327 QList<QToolBar*> pvToolbars = myGuiElements->getToolbars();
328 foreach(QToolBar* aBar, pvToolbars) {
329 if (!myToolbars.contains(aBar)) {
330 myToolbars[aBar] = true;
331 myToolbarBreaks[aBar] = false;
332 aBar->setVisible(false);
333 aBar->toggleViewAction()->setVisible(false);
337 // process other toolbars (possibly added by Paraview)
338 QList<QToolBar*> allToolbars = aDesktop->findChildren<QToolBar*>();
339 foreach(QToolBar* aBar, allToolbars) {
340 if (!foreignToolbars.contains(aBar) && !myToolbars.contains(aBar)) {
341 myToolbars[aBar] = true;
342 myToolbarBreaks[aBar] = false;
343 aBar->setVisible(false);
344 aBar->toggleViewAction()->setVisible(false);
350 SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr();
351 bool isStop = aResourceMgr->booleanValue( PARAVIS_MODULE_NAME, "stop_trace", false );
354 // Start a timer to schedule asap:
356 myInitTimer = new QTimer(aDesktop);
357 QObject::connect(myInitTimer, SIGNAL(timeout()), this, SLOT(onInitTimer()) );
358 myInitTimer->setSingleShot(true);
359 myInitTimer->start(0);
362 this->VTKConnect = vtkEventQtSlotConnect::New();
364 vtkProcessModule* pm = vtkProcessModule::GetProcessModule();
366 vtkPVSession* pvs = dynamic_cast<vtkPVSession*>(pm->GetSession());
368 vtkPVProgressHandler* ph = pvs->GetProgressHandler();
370 this->VTKConnect->Connect(ph, vtkCommand::StartEvent,
371 this, SLOT(onStartProgress()));
372 this->VTKConnect->Connect(ph, vtkCommand::EndEvent,
373 this, SLOT(onEndProgress()));
377 connect( application(), SIGNAL( appClosed() ), this, SLOT( onStopTrace() ) );
381 * \brief Slot called when the progress bar starts.
383 void PVGUI_Module::onStartProgress()
385 // VSR 19/03/2015, issue 0023025
386 // next line is commented: it is bad idea to show wait cursor on ANY vtk event
387 // moreover, it does not work when running pvserver with --multi-client mode
388 //QApplication::setOverrideCursor(Qt::WaitCursor);
392 * \brief Slot called when the progress bar is done.
394 void PVGUI_Module::onEndProgress()
396 // VSR 19/03/2015, issue 0023025
397 // next line is commented: it is bad idea to show wait cursor on ANY vtk event
398 // moreover, it does not work when running pvserver with --multi-client mode
399 //QApplication::restoreOverrideCursor();
402 void PVGUI_Module::onDataRepresentationUpdated() {
403 LightApp_Study* activeStudy = dynamic_cast<LightApp_Study*>(application()->activeStudy());
404 if(!activeStudy) return;
406 activeStudy->Modified();
410 \brief Initialisation timer event - Starts up the Python trace
412 void PVGUI_Module::onInitTimer()
418 \brief Get list of embedded macros files
420 QStringList PVGUI_Module::getEmbeddedMacrosList()
422 QString aRootDir = getenv("PARAVIS_ROOT_DIR");
424 QString aSourcePath = aRootDir + "/bin/salome/Macro";
429 QDir aSourceDir(aSourcePath);
430 QStringList aSourceFiles = aSourceDir.entryList(aFilter, QDir::Files);
431 QStringList aFullPathSourceFiles;
432 foreach (QString aMacrosName, aSourceFiles) {
433 aFullPathSourceFiles << aSourceDir.absoluteFilePath(aMacrosName);
435 return aFullPathSourceFiles;
439 \brief Update the list of embedded macros
441 void PVGUI_Module::updateMacros()
443 pqPythonManager* aPythonManager = pqPVApplicationCore::instance()->pythonManager();
444 if(!aPythonManager) {
448 foreach (QString aStr, getEmbeddedMacrosList()) {
449 aPythonManager->addMacro(aStr);
455 \brief Get list of compliant dockable GUI elements
456 \param m map to be filled in ("type":"default_position")
458 void PVGUI_Module::windows( QMap<int, int>& m ) const
460 m.insert( LightApp_Application::WT_ObjectBrowser, Qt::LeftDockWidgetArea );
461 #ifndef DISABLE_PYCONSOLE
462 m.insert( LightApp_Application::WT_PyConsole, Qt::BottomDockWidgetArea );
464 // ParaView diagnostic output redirected here
465 m.insert( LightApp_Application::WT_LogWindow, Qt::BottomDockWidgetArea );
469 \brief Shows (toShow = true) or hides ParaView view window
471 void PVGUI_Module::showView( bool toShow )
473 // VSR: TODO: all below is not needed, if we use standard approach
474 // that consists in implementing viewManagers() function properly
475 // This should be done after we decide what to do with Log window.
476 LightApp_Application* anApp = getApp();
477 PVViewer_ViewManager* viewMgr =
478 dynamic_cast<PVViewer_ViewManager*>( anApp->getViewManager( PVViewer_Viewer::Type(), false ) );
480 viewMgr = new PVViewer_ViewManager( anApp->activeStudy(), anApp->desktop(), anApp->logWindow() );
481 anApp->addViewManager( viewMgr );
482 connect( viewMgr, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
483 anApp, SLOT( onCloseView( SUIT_ViewManager* ) ) );
486 PVViewer_ViewWindow* pvWnd = dynamic_cast<PVViewer_ViewWindow*>( viewMgr->getActiveView() );
488 pvWnd = dynamic_cast<PVViewer_ViewWindow*>( viewMgr->createViewWindow() );
489 // this also connects to the pvserver and instantiates relevant PV behaviors
492 pvWnd->setVisible( toShow );
493 if ( toShow ) pvWnd->setFocus();
497 \brief Slot to show help for proxy.
499 void PVGUI_Module::showHelpForProxy( const QString& groupname, const QString& proxyname )
501 pqHelpReaction::showProxyHelp(groupname, proxyname);
505 \brief Slot to show the waiting state.
507 void PVGUI_Module::onPreAccept()
509 getApp()->desktop()->statusBar()->showMessage(tr("STB_PREACCEPT"));
510 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
514 \brief Slot to show the ready state.
516 void PVGUI_Module::onPostAccept()
518 getApp()->desktop()->statusBar()->showMessage(tr("STB_POSTACCEPT"), 2000);
519 QTimer::singleShot(0, this, SLOT(endWaitCursor()));
523 \brief Slot to switch off wait cursor.
525 void PVGUI_Module::endWaitCursor()
527 QApplication::restoreOverrideCursor();
529 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
531 \brief Handler method for the output of messages.
533 static void ParavisMessageOutput(QtMsgType type, const char *msg)
538 vtkOutputWindow::GetInstance()->DisplayText(msg);
541 vtkOutputWindow::GetInstance()->DisplayErrorText(msg);
544 vtkOutputWindow::GetInstance()->DisplayErrorText(msg);
547 vtkOutputWindow::GetInstance()->DisplayErrorText(msg);
553 \brief Handler method for the output of messages.
555 static void ParavisMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
560 vtkOutputWindow::GetInstance()->DisplayText(msg.toLatin1().constData());
563 vtkOutputWindow::GetInstance()->DisplayErrorText(msg.toLatin1().constData());
566 vtkOutputWindow::GetInstance()->DisplayErrorText(msg.toLatin1().constData());
569 vtkOutputWindow::GetInstance()->DisplayErrorText(msg.toLatin1().constData());
575 \brief Activate module.
576 \param study current study
577 \return \c true if activaion is done successfully or 0 to prevent
580 bool PVGUI_Module::activateModule( SUIT_Study* study )
582 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
583 myOldMsgHandler = qInstallMsgHandler(ParavisMessageOutput);
585 myOldMsgHandler = qInstallMessageHandler(ParavisMessageOutput);
587 SUIT_ExceptionHandler::addCleanUpRoutine( paravisCleanUp );
589 storeCommonWindowsState();
591 bool isDone = LightApp_Module::activateModule( study );
592 if ( !isDone ) return false;
595 if ( mySourcesMenuId != -1 ) menuMgr()->show(mySourcesMenuId);
596 if ( myFiltersMenuId != -1 ) menuMgr()->show(myFiltersMenuId);
597 if ( myMacrosMenuId != -1 ) menuMgr()->show(myMacrosMenuId);
599 // Update the various menus with the content pre-loaded in myGuiElements
600 // QMenu* srcMenu = menuMgr()->findMenu( mySourcesMenuId );
601 // myGuiElements->updateSourcesMenu(srcMenu);
602 // QMenu* filtMenu = menuMgr()->findMenu( myFiltersMenuId );
603 // myGuiElements->updateFiltersMenu(filtMenu);
604 // QMenu* macMenu = menuMgr()->findMenu( myMacrosMenuId );
605 // myGuiElements->updateMacrosMenu(macMenu);
607 setMenuShown( true );
608 setToolShown( true );
610 restoreDockWidgetsState();
612 QMenu* aMenu = menuMgr()->findMenu( myRecentMenuId );
614 QList<QAction*> anActns = aMenu->actions();
615 for (int i = 0; i < anActns.size(); ++i) {
616 QAction* a = anActns.at(i);
622 QList<QMenu*>::iterator it;
623 for (it = myMenus.begin(); it != myMenus.end(); ++it) {
624 QAction* a = (*it)->menuAction();
629 if ( myRecentMenuId != -1 ) menuMgr()->show(myRecentMenuId);
636 \brief Deactivate module.
637 \param study current study
638 \return \c true if deactivaion is done successfully or 0 to prevent
639 deactivation on error
641 bool PVGUI_Module::deactivateModule( SUIT_Study* study )
643 MESSAGE("PARAVIS deactivation ...")
645 QMenu* aMenu = menuMgr()->findMenu( myRecentMenuId );
647 QList<QAction*> anActns = aMenu->actions();
648 for (int i = 0; i < anActns.size(); ++i) {
649 QAction* a = anActns.at(i);
651 a->setVisible(false);
655 QList<QMenu*>::iterator it;
656 for (it = myMenus.begin(); it != myMenus.end(); ++it) {
657 QAction* a = (*it)->menuAction();
659 a->setVisible(false);
662 QList<QDockWidget*> aStreamingViews = application()->desktop()->findChildren<QDockWidget*>("pqStreamingControls");
663 foreach(QDockWidget* aView, aStreamingViews) {
664 if (!myDockWidgets.contains(aView))
665 myDockWidgets[aView] = aView->isVisible();
668 /*if (pqImplementation::helpWindow) {
669 pqImplementation::helpWindow->hide();
672 menuMgr()->hide(myRecentMenuId);
673 menuMgr()->hide(mySourcesMenuId);
674 menuMgr()->hide(myFiltersMenuId);
675 menuMgr()->hide(myMacrosMenuId);
676 setMenuShown( false );
677 setToolShown( false );
679 saveDockWidgetsState();
681 SUIT_ExceptionHandler::removeCleanUpRoutine( paravisCleanUp );
684 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
685 qInstallMsgHandler(myOldMsgHandler);
687 qInstallMessageHandler(myOldMsgHandler);
689 restoreCommonWindowsState();
691 return LightApp_Module::deactivateModule( study );
696 \brief Called when application is closed.
698 Process finalize application functionality from ParaView in order to save server settings
699 and nullify application pointer if the application is being closed.
701 \param theApp application
703 void PVGUI_Module::onApplicationClosed( SUIT_Application* theApp )
705 PVViewer_Core::ParaviewCleanup();
706 CAM_Module::onApplicationClosed(theApp);
710 \brief Called when study is closed.
712 Removes data model from the \a study.
714 \param study study being closed
716 void PVGUI_Module::studyClosed(SUIT_Study* study)
718 showView(false); // VSR: this seems to be not needed (all views are automatically closed)
719 clearParaviewState();
723 LightApp_Module::studyClosed(study);
727 \brief Open file of format supported by ParaView
729 void PVGUI_Module::openFile( const char* theName )
733 pqLoadDataReaction::loadData( aFiles );
737 \brief Starts Python trace.
739 Start trace invoking the newly introduced C++ API (PV 4.2)
740 (inspired from pqTraceReaction::start())
742 void PVGUI_Module::startTrace()
744 vtkSMSessionProxyManager* pxm = pqActiveObjects::instance().activeServer()->proxyManager();
746 vtkSmartPointer<vtkSMProxy> proxy;
747 proxy.TakeReference( pxm->NewProxy( "pythontracing", "PythonTraceOptions" ) );
749 vtkNew<vtkSMParaViewPipelineController> controller;
750 controller->InitializeProxy( proxy );
752 vtkSMTrace* trace = vtkSMTrace::StartTrace();
754 // Set manually the properties entered via the dialog box poping-up when requiring
755 // a trace start in PV4.2 (trace options)
756 SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr();
757 int type = aResourceMgr->integerValue( PARAVIS_MODULE_NAME, "tracestate_type", 2 );
758 trace->SetPropertiesToTraceOnCreate( type );
759 trace->SetFullyTraceSupplementalProxies( false );
764 \brief Stops Python trace.
766 void PVGUI_Module::stopTrace()
768 vtkSMTrace::StopTrace();
772 \brief Execute a Python script.
774 void PVGUI_Module::executeScript( const char* script )
777 pqPythonManager* manager = qobject_cast<pqPythonManager*>(
778 pqApplicationCore::instance()->manager( "PYTHON_MANAGER" ) );
780 pqPythonDialog* pyDiag = manager->pythonShellDialog();
782 pyDiag->runString(script);
789 // * Debug function printing out the given interpreter's execution context
791 //void printInterpContext(PyInterp_Interp * interp )
793 // // Extract __smtraceString from interpreter's context
794 // const PyObject* ctxt = interp->getExecutionContext();
796 // PyObject* lst = PyDict_Keys((PyObject *)ctxt);
797 // Py_ssize_t siz = PyList_GET_SIZE(lst);
798 // for (Py_ssize_t i = 0; i < siz; i++)
800 // PyObject * elem = PyList_GetItem(lst, i);
801 // if (PyString_Check(elem))
803 // std::cout << "At pos:" << i << ", " << Py_EncodeLocale(PyUnicode_AS_UNICODE(elem), NULL) << std::endl;
806 // std::cout << "At pos:" << i << ", not a string!" << std::endl;
812 \brief Returns trace string
814 QString PVGUI_Module::getTraceString()
816 QString traceString = "";
818 static const QString replaceStr( "paraview.simple" );
819 std::stringstream nl;
820 nl << std::endl; // surely there is some Qt trick to do that in a portable way??
821 QString end_line( nl.str().c_str() );
823 vtkSMTrace* tracer = vtkSMTrace::GetActiveTracer();
825 traceString = tracer->GetCurrentTrace();
826 // 'import pvsimple' is necessary to fix the first call to DisableFirstRenderCamera in the paraview trace
827 // 'ShowParaviewView()' ensure there is an opened viewing window (otherwise SEGFAULT!)
828 traceString = "import pvsimple" + end_line +
829 "pvsimple.ShowParaviewView()" + end_line + traceString;
831 // Replace import "paraview.simple" by "pvsimple"
832 if ( !traceString.isEmpty() ) {
833 int aPos = traceString.indexOf( replaceStr );
834 while ( aPos != -1 ) {
835 traceString = traceString.replace( aPos, replaceStr.length(), "pvsimple" );
836 aPos = traceString.indexOf( replaceStr, aPos );
841 // Save camera position to, which is no longer output by the tracer ...
843 vtkPythonScopeGilEnsurer psge;
844 PyObject * mods(PySys_GetObject(const_cast<char*>("modules")));
845 PyObject * trace_mod(PyDict_GetItemString(mods, "paraview.smtrace")); // module was already (really) imported by vtkSMTrace
846 if (PyModule_Check(trace_mod)) {
847 vtkSmartPyObject save_cam(PyObject_GetAttrString(trace_mod, const_cast<char*>("SaveCameras")));
848 vtkSmartPyObject camera_trace(PyObject_CallMethod(save_cam, const_cast<char*>("get_trace"), NULL));
849 // Convert to a single string
850 vtkSmartPyObject ret(PyUnicode_FromUnicode(Py_DecodeLocale(end_line.toStdString().c_str(), NULL), end_line.size()));
851 vtkSmartPyObject final_string(PyObject_CallMethod(ret, const_cast<char*>("join"),
852 const_cast<char*>("O"), (PyObject*)camera_trace));
853 if (PyUnicode_CheckExact(final_string))
855 QString camera_qs(Py_EncodeLocale(PyUnicode_AS_UNICODE(final_string.GetPointer()), NULL)); // deep copy
856 traceString = traceString + end_line + end_line + QString("#### saving camera placements for all active views")
857 + end_line + end_line + camera_qs + end_line;
866 \brief Saves trace string to disk file
868 void PVGUI_Module::saveTrace( const char* theName )
870 QFile file( theName );
871 if ( !file.open( QIODevice::WriteOnly | QIODevice::Text ) ) {
872 MESSAGE( "Could not open file:" << theName );
875 QTextStream out( &file );
876 out << getTraceString();
881 \brief Saves ParaView state to a disk file
883 void PVGUI_Module::saveParaviewState( const QString& theFileName )
885 pqApplicationCore::instance()->saveState( theFileName.toStdString().c_str() );
889 \brief Delete all objects for Paraview Pipeline Browser
891 void PVGUI_Module::clearParaviewState()
893 QAction* deleteAllAction = action( DeleteAllId );
894 if ( deleteAllAction ) {
895 deleteAllAction->activate( QAction::Trigger );
900 \brief Restores ParaView state from a disk file
902 void PVGUI_Module::loadParaviewState( const QString& theFileName )
904 pqApplicationCore::instance()->loadState( theFileName.toStdString().c_str(), getActiveServer() );
908 \brief Returns current active ParaView server
910 pqServer* PVGUI_Module::getActiveServer()
912 return pqApplicationCore::instance()->getActiveServer();
917 \brief Creates PARAVIS preferences panel.
919 void PVGUI_Module::createPreferences()
921 QList<QVariant> aIndices;
922 QStringList aStrings;
924 // Paraview settings tab
925 int aParaViewSettingsTab = addPreference( tr( "TIT_PVIEWSETTINGS" ) );
927 setPreferenceProperty(aParaViewSettingsTab, "stretch", false );
928 int aPanel = addPreference( QString(), aParaViewSettingsTab,
929 LightApp_Preferences::UserDefined, PARAVIS_MODULE_NAME, "" );
931 setPreferenceProperty( aPanel, "content", (qint64)( new PVGUI_ParaViewSettingsPane( 0, getApp() ) ) );
933 // Paravis settings tab
934 int aParaVisSettingsTab = addPreference( tr( "TIT_PVISSETTINGS" ) );
936 addPreference( tr( "PREF_NO_EXT_PVSERVER" ), aParaVisSettingsTab,
937 LightApp_Preferences::Bool, PARAVIS_MODULE_NAME, "no_ext_pv_server" );
939 int aSaveType = addPreference( tr( "PREF_SAVE_TYPE_LBL" ), aParaVisSettingsTab,
940 LightApp_Preferences::Selector,
941 PARAVIS_MODULE_NAME, "savestate_type" );
945 aIndices << 0 << 1 << 2;
946 aStrings << tr("PREF_SAVE_TYPE_0") << tr("PREF_SAVE_TYPE_1") << tr("PREF_SAVE_TYPE_2");
947 setPreferenceProperty( aSaveType, "strings", aStrings );
948 setPreferenceProperty( aSaveType, "indexes", aIndices );
950 // ... "Language" group <<start>>
951 int traceGroup = addPreference( tr( "PREF_GROUP_TRACE" ), aParaVisSettingsTab );
953 int stopTrace = addPreference( tr( "PREF_STOP_TRACE" ), traceGroup,
954 LightApp_Preferences::Bool, PARAVIS_MODULE_NAME, "stop_trace" );
955 setPreferenceProperty( stopTrace, "restart", true );
957 int aTraceType = addPreference( tr( "PREF_TRACE_TYPE_LBL" ), traceGroup,
958 LightApp_Preferences::Selector,
959 PARAVIS_MODULE_NAME, "tracestate_type" );
962 aIndices << 0 << 1 << 2;
963 aStrings << tr("PREF_TRACE_TYPE_0") << tr("PREF_TRACE_TYPE_1") << tr("PREF_TRACE_TYPE_2");
964 setPreferenceProperty( aTraceType, "strings", aStrings );
965 setPreferenceProperty( aTraceType, "indexes", aIndices );
966 setPreferenceProperty( aTraceType, "restart", true );
970 \brief. Show ParaView python trace.
972 void PVGUI_Module::onShowTrace()
974 if (!myTraceWindow) {
975 myTraceWindow = new pqPythonScriptEditor(getApp()->desktop());
977 myTraceWindow->setText(getTraceString());
978 myTraceWindow->show();
979 myTraceWindow->raise();
980 myTraceWindow->activateWindow();
985 \brief. Re-initialize ParaView python trace.
987 void PVGUI_Module::onRestartTrace()
994 \brief. Close ParaView python trace.
996 void PVGUI_Module::onStopTrace()
1001 \brief Called when view manager is added
1003 void PVGUI_Module::onViewManagerAdded( SUIT_ViewManager* vm )
1005 if ( PVViewer_ViewManager* pvvm = dynamic_cast<PVViewer_ViewManager*>( vm ) ) {
1006 connect( pvvm, SIGNAL( viewCreated( SUIT_ViewWindow* ) ),
1007 this, SLOT( onPVViewCreated( SUIT_ViewWindow* ) ) );
1008 connect( pvvm, SIGNAL( deleteView( SUIT_ViewWindow* ) ),
1009 this, SLOT( onPVViewDelete( SUIT_ViewWindow* ) ) );
1014 \brief Called when view manager is removed
1016 void PVGUI_Module::onViewManagerRemoved( SUIT_ViewManager* vm )
1018 if ( PVViewer_ViewManager* pvvm = dynamic_cast<PVViewer_ViewManager*>( vm ) )
1019 disconnect( pvvm, SIGNAL( viewCreated( SUIT_ViewWindow* ) ),
1020 this, SLOT( onPVViewCreated( SUIT_ViewWindow* ) ) );
1024 \brief Show toolbars at \a vw PV view window creating when PARAVIS is active.
1026 void PVGUI_Module::onPVViewCreated( SUIT_ViewWindow* vw )
1028 myGuiElements->setToolBarVisible( true );
1029 restoreDockWidgetsState();
1033 \brief Save toolbars state at \a view view closing.
1035 void PVGUI_Module::onPVViewDelete( SUIT_ViewWindow* view )
1037 if ( dynamic_cast<PVViewer_ViewWindow*>( view ) )
1038 saveDockWidgetsState( false );
1042 \fn CAM_Module* createModule();
1043 \brief Export module instance (factory function).
1044 \return new created instance of the module
1048 #define PVGUI_EXPORT __declspec(dllexport)
1050 #define PVGUI_EXPORT
1056 PVGUI_EXPORT CAM_Module* createModule() {
1057 return new PVGUI_Module();
1060 PVGUI_EXPORT char* getModuleVersion() {
1061 return (char*)PARAVIS_VERSION_STR;