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 ),
184 myCatalystMenuId(-1),
191 Q_INIT_RESOURCE( PVGUI );
193 ParavisModule = this;
195 // Clear old copies of embedded macros files
196 QString aDestPath = QString( "%1/.config/%2/Macros" ).arg( QDir::homePath() ).arg( QApplication::applicationName() );
200 QDir aDestDir(aDestPath);
201 QStringList aDestFiles = aDestDir.entryList(aFilter, QDir::Files);
202 foreach (QString aMacrosPath, getEmbeddedMacrosList()) {
203 QString aMacrosName = QFileInfo(aMacrosPath).fileName();
204 if (aDestFiles.contains(aMacrosName)) {
205 aDestDir.remove(aMacrosName);
213 PVGUI_Module::~PVGUI_Module()
220 \brief Retrieve the PVSERVER CORBA engine.
221 This uses the Python wrapper provided
222 by the PVViewer code in GUI (class PVViewer_EngineWrapper).
225 PVServer_ServiceWrapper* PVGUI_Module::GetEngine()
227 return PVServer_ServiceWrapper::GetInstance();
231 \brief Create data model.
232 \return module specific data model
234 CAM_DataModel* PVGUI_Module::createDataModel()
236 return new PVGUI_DataModel( this );
240 \brief Get the ParaView application singleton.
242 pqPVApplicationCore* PVGUI_Module::GetPVApplication()
244 return PVViewer_Core::GetPVApplication();
248 \brief Initialize module. Creates menus, prepares context menu, etc.
249 \param app SALOME GUI application instance
251 void PVGUI_Module::initialize( CAM_Application* app )
253 LightApp_Module::initialize( app );
255 // Uncomment to debug ParaView initialization
256 // "aa" used instead of "i" as GDB doesn't like "i" variables :)
264 LightApp_Application* anApp = getApp();
265 SUIT_Desktop* aDesktop = anApp->desktop();
267 // Remember current state of desktop toolbars
268 QList<QToolBar*> foreignToolbars = aDesktop->findChildren<QToolBar*>();
270 // Initialize ParaView client and associated behaviors
271 // and connect to externally launched pvserver
272 PVViewer_Core::ParaviewInitApp(aDesktop, anApp->logWindow());
273 myGuiElements = PVViewer_GUIElements::GetInstance(aDesktop);
275 // [ABN]: careful with the order of the GUI element creation, the loading of the configuration
276 // and the connection to the server. This order is very sensitive if one wants to make
277 // sure all menus, etc ... are correctly populated.
278 // Reference points are: ParaViewMainWindow.cxx and branded_paraview_initializer.cxx.in
285 PVViewer_Core::ParaviewInitBehaviors(true, aDesktop);
287 QList<QDockWidget*> activeDocks = aDesktop->findChildren<QDockWidget*>();
288 QList<QMenu*> activeMenus = aDesktop->findChildren<QMenu*>();
290 // Setup quick-launch shortcuts.
291 QShortcut *ctrlSpace = new QShortcut(Qt::CTRL + Qt::Key_Space, aDesktop);
292 QObject::connect(ctrlSpace, SIGNAL(activated()),
293 pqApplicationCore::instance(), SLOT(quickLaunch()));
295 // Find Plugin Dock Widgets
296 QList<QDockWidget*> currentDocks = aDesktop->findChildren<QDockWidget*>();
297 QList<QDockWidget*>::iterator i;
298 for (i = currentDocks.begin(); i != currentDocks.end(); ++i) {
299 if(!activeDocks.contains(*i)) {
300 myDockWidgets[*i] = false; // hidden by default
306 // [ABN] TODO: fix this - triggers a SEGFAULT at deactivation() time.
307 // QList<QMenu*> currentMenus = aDesktop->findChildren<QMenu*>();
308 // QList<QMenu*>::iterator im;
309 // for (im = currentMenus.begin(); im != currentMenus.end(); ++im) {
310 // if(!activeMenus.contains(*im)) {
311 // QString s = (*im)->title();
312 // std::cout << " MENU "<< s.toStdString() << std::endl;
313 // myMenus.append(*im);
317 // Connect after toolbar creation, etc ... as some activations of the toolbars is triggered
318 // by the ServerConnection event:
319 const QString configPath(PVViewer_ViewManager::GetPVConfigPath());
320 PVViewer_Core::ParaviewLoadConfigurations(configPath, true);
321 PVViewer_ViewManager::ConnectToExternalPVServer(aDesktop);
324 // Find created toolbars
325 QCoreApplication::processEvents();
327 // process PVViewer toolbars (might be added by PVViewer created BEFORE activating ParaVis)
328 QList<QToolBar*> pvToolbars = myGuiElements->getToolbars();
329 foreach(QToolBar* aBar, pvToolbars) {
330 if (!myToolbars.contains(aBar)) {
331 myToolbars[aBar] = true;
332 myToolbarBreaks[aBar] = false;
333 aBar->setVisible(false);
334 aBar->toggleViewAction()->setVisible(false);
338 // process other toolbars (possibly added by Paraview)
339 QList<QToolBar*> allToolbars = aDesktop->findChildren<QToolBar*>();
340 foreach(QToolBar* aBar, allToolbars) {
341 if (!foreignToolbars.contains(aBar) && !myToolbars.contains(aBar)) {
342 myToolbars[aBar] = true;
343 myToolbarBreaks[aBar] = false;
344 aBar->setVisible(false);
345 aBar->toggleViewAction()->setVisible(false);
351 SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr();
352 bool isStop = aResourceMgr->booleanValue( PARAVIS_MODULE_NAME, "stop_trace", false );
355 // Start a timer to schedule asap:
357 myInitTimer = new QTimer(aDesktop);
358 QObject::connect(myInitTimer, SIGNAL(timeout()), this, SLOT(onInitTimer()) );
359 myInitTimer->setSingleShot(true);
360 myInitTimer->start(0);
363 this->VTKConnect = vtkEventQtSlotConnect::New();
365 vtkProcessModule* pm = vtkProcessModule::GetProcessModule();
367 vtkPVSession* pvs = dynamic_cast<vtkPVSession*>(pm->GetSession());
369 vtkPVProgressHandler* ph = pvs->GetProgressHandler();
371 this->VTKConnect->Connect(ph, vtkCommand::StartEvent,
372 this, SLOT(onStartProgress()));
373 this->VTKConnect->Connect(ph, vtkCommand::EndEvent,
374 this, SLOT(onEndProgress()));
378 connect( application(), SIGNAL( appClosed() ), this, SLOT( onStopTrace() ) );
382 * \brief Slot called when the progress bar starts.
384 void PVGUI_Module::onStartProgress()
386 // VSR 19/03/2015, issue 0023025
387 // next line is commented: it is bad idea to show wait cursor on ANY vtk event
388 // moreover, it does not work when running pvserver with --multi-client mode
389 //QApplication::setOverrideCursor(Qt::WaitCursor);
393 * \brief Slot called when the progress bar is done.
395 void PVGUI_Module::onEndProgress()
397 // VSR 19/03/2015, issue 0023025
398 // next line is commented: it is bad idea to show wait cursor on ANY vtk event
399 // moreover, it does not work when running pvserver with --multi-client mode
400 //QApplication::restoreOverrideCursor();
403 void PVGUI_Module::onDataRepresentationUpdated() {
404 LightApp_Study* activeStudy = dynamic_cast<LightApp_Study*>(application()->activeStudy());
405 if(!activeStudy) return;
407 activeStudy->Modified();
411 \brief Initialisation timer event - Starts up the Python trace
413 void PVGUI_Module::onInitTimer()
419 \brief Get list of embedded macros files
421 QStringList PVGUI_Module::getEmbeddedMacrosList()
423 QString aRootDir = getenv("PARAVIS_ROOT_DIR");
425 QString aSourcePath = aRootDir + "/bin/salome/Macro";
430 QDir aSourceDir(aSourcePath);
431 QStringList aSourceFiles = aSourceDir.entryList(aFilter, QDir::Files);
432 QStringList aFullPathSourceFiles;
433 foreach (QString aMacrosName, aSourceFiles) {
434 aFullPathSourceFiles << aSourceDir.absoluteFilePath(aMacrosName);
436 return aFullPathSourceFiles;
440 \brief Update the list of embedded macros
442 void PVGUI_Module::updateMacros()
444 pqPythonManager* aPythonManager = pqPVApplicationCore::instance()->pythonManager();
445 if(!aPythonManager) {
449 foreach (QString aStr, getEmbeddedMacrosList()) {
450 aPythonManager->addMacro(aStr);
456 \brief Get list of compliant dockable GUI elements
457 \param m map to be filled in ("type":"default_position")
459 void PVGUI_Module::windows( QMap<int, int>& m ) const
461 m.insert( LightApp_Application::WT_ObjectBrowser, Qt::LeftDockWidgetArea );
462 #ifndef DISABLE_PYCONSOLE
463 m.insert( LightApp_Application::WT_PyConsole, Qt::BottomDockWidgetArea );
465 // ParaView diagnostic output redirected here
466 m.insert( LightApp_Application::WT_LogWindow, Qt::BottomDockWidgetArea );
470 \brief Shows (toShow = true) or hides ParaView view window
472 void PVGUI_Module::showView( bool toShow )
474 // VSR: TODO: all below is not needed, if we use standard approach
475 // that consists in implementing viewManagers() function properly
476 // This should be done after we decide what to do with Log window.
477 LightApp_Application* anApp = getApp();
478 PVViewer_ViewManager* viewMgr =
479 dynamic_cast<PVViewer_ViewManager*>( anApp->getViewManager( PVViewer_Viewer::Type(), false ) );
481 viewMgr = new PVViewer_ViewManager( anApp->activeStudy(), anApp->desktop(), anApp->logWindow() );
482 anApp->addViewManager( viewMgr );
483 connect( viewMgr, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
484 anApp, SLOT( onCloseView( SUIT_ViewManager* ) ) );
487 PVViewer_ViewWindow* pvWnd = dynamic_cast<PVViewer_ViewWindow*>( viewMgr->getActiveView() );
489 pvWnd = dynamic_cast<PVViewer_ViewWindow*>( viewMgr->createViewWindow() );
490 // this also connects to the pvserver and instantiates relevant PV behaviors
493 pvWnd->setVisible( toShow );
494 if ( toShow ) pvWnd->setFocus();
498 \brief Slot to show help for proxy.
500 void PVGUI_Module::showHelpForProxy( const QString& groupname, const QString& proxyname )
502 pqHelpReaction::showProxyHelp(groupname, proxyname);
506 \brief Slot to show the waiting state.
508 void PVGUI_Module::onPreAccept()
510 getApp()->desktop()->statusBar()->showMessage(tr("STB_PREACCEPT"));
511 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
515 \brief Slot to show the ready state.
517 void PVGUI_Module::onPostAccept()
519 getApp()->desktop()->statusBar()->showMessage(tr("STB_POSTACCEPT"), 2000);
520 QTimer::singleShot(0, this, SLOT(endWaitCursor()));
524 \brief Slot to switch off wait cursor.
526 void PVGUI_Module::endWaitCursor()
528 QApplication::restoreOverrideCursor();
530 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
532 \brief Handler method for the output of messages.
534 static void ParavisMessageOutput(QtMsgType type, const char *msg)
539 vtkOutputWindow::GetInstance()->DisplayText(msg);
542 vtkOutputWindow::GetInstance()->DisplayErrorText(msg);
545 vtkOutputWindow::GetInstance()->DisplayErrorText(msg);
548 vtkOutputWindow::GetInstance()->DisplayErrorText(msg);
554 \brief Handler method for the output of messages.
556 static void ParavisMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
561 vtkOutputWindow::GetInstance()->DisplayText(msg.toLatin1().constData());
564 vtkOutputWindow::GetInstance()->DisplayErrorText(msg.toLatin1().constData());
567 vtkOutputWindow::GetInstance()->DisplayErrorText(msg.toLatin1().constData());
570 vtkOutputWindow::GetInstance()->DisplayErrorText(msg.toLatin1().constData());
576 \brief Activate module.
577 \param study current study
578 \return \c true if activaion is done successfully or 0 to prevent
581 bool PVGUI_Module::activateModule( SUIT_Study* study )
583 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
584 myOldMsgHandler = qInstallMsgHandler(ParavisMessageOutput);
586 myOldMsgHandler = qInstallMessageHandler(ParavisMessageOutput);
588 SUIT_ExceptionHandler::addCleanUpRoutine( paravisCleanUp );
590 storeCommonWindowsState();
592 bool isDone = LightApp_Module::activateModule( study );
593 if ( !isDone ) return false;
596 if ( mySourcesMenuId != -1 ) menuMgr()->show(mySourcesMenuId);
597 if ( myFiltersMenuId != -1 ) menuMgr()->show(myFiltersMenuId);
598 if ( myMacrosMenuId != -1 ) menuMgr()->show(myMacrosMenuId);
599 if ( myCatalystMenuId != -1 ) menuMgr()->show(myCatalystMenuId);
601 // Update the various menus with the content pre-loaded in myGuiElements
602 // QMenu* srcMenu = menuMgr()->findMenu( mySourcesMenuId );
603 // myGuiElements->updateSourcesMenu(srcMenu);
604 // QMenu* filtMenu = menuMgr()->findMenu( myFiltersMenuId );
605 // myGuiElements->updateFiltersMenu(filtMenu);
606 // QMenu* macMenu = menuMgr()->findMenu( myMacrosMenuId );
607 // myGuiElements->updateMacrosMenu(macMenu);
609 setMenuShown( true );
610 setToolShown( true );
612 restoreDockWidgetsState();
614 QMenu* aMenu = menuMgr()->findMenu( myRecentMenuId );
616 QList<QAction*> anActns = aMenu->actions();
617 for (int i = 0; i < anActns.size(); ++i) {
618 QAction* a = anActns.at(i);
624 QList<QMenu*>::iterator it;
625 for (it = myMenus.begin(); it != myMenus.end(); ++it) {
626 QAction* a = (*it)->menuAction();
631 if ( myRecentMenuId != -1 ) menuMgr()->show(myRecentMenuId);
638 \brief Deactivate module.
639 \param study current study
640 \return \c true if deactivaion is done successfully or 0 to prevent
641 deactivation on error
643 bool PVGUI_Module::deactivateModule( SUIT_Study* study )
645 MESSAGE("PARAVIS deactivation ...")
647 QMenu* aMenu = menuMgr()->findMenu( myRecentMenuId );
649 QList<QAction*> anActns = aMenu->actions();
650 for (int i = 0; i < anActns.size(); ++i) {
651 QAction* a = anActns.at(i);
653 a->setVisible(false);
657 QList<QMenu*>::iterator it;
658 for (it = myMenus.begin(); it != myMenus.end(); ++it) {
659 QAction* a = (*it)->menuAction();
661 a->setVisible(false);
664 QList<QDockWidget*> aStreamingViews = application()->desktop()->findChildren<QDockWidget*>("pqStreamingControls");
665 foreach(QDockWidget* aView, aStreamingViews) {
666 if (!myDockWidgets.contains(aView))
667 myDockWidgets[aView] = aView->isVisible();
670 /*if (pqImplementation::helpWindow) {
671 pqImplementation::helpWindow->hide();
674 menuMgr()->hide(myRecentMenuId);
675 menuMgr()->hide(mySourcesMenuId);
676 menuMgr()->hide(myFiltersMenuId);
677 menuMgr()->hide(myMacrosMenuId);
678 menuMgr()->hide(myCatalystMenuId);
679 setMenuShown( false );
680 setToolShown( false );
682 saveDockWidgetsState();
684 SUIT_ExceptionHandler::removeCleanUpRoutine( paravisCleanUp );
687 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
688 qInstallMsgHandler(myOldMsgHandler);
690 qInstallMessageHandler(myOldMsgHandler);
692 restoreCommonWindowsState();
694 return LightApp_Module::deactivateModule( study );
699 \brief Called when application is closed.
701 Process finalize application functionality from ParaView in order to save server settings
702 and nullify application pointer if the application is being closed.
704 \param theApp application
706 void PVGUI_Module::onApplicationClosed( SUIT_Application* theApp )
708 PVViewer_Core::ParaviewCleanup();
709 CAM_Module::onApplicationClosed(theApp);
713 \brief Called when study is closed.
715 Removes data model from the \a study.
717 \param study study being closed
719 void PVGUI_Module::studyClosed(SUIT_Study* study)
721 showView(false); // VSR: this seems to be not needed (all views are automatically closed)
722 clearParaviewState();
726 LightApp_Module::studyClosed(study);
730 \brief Open file of format supported by ParaView
732 void PVGUI_Module::openFile( const char* theName )
736 pqLoadDataReaction::loadData( aFiles );
740 \brief Starts Python trace.
742 Start trace invoking the newly introduced C++ API (PV 4.2)
743 (inspired from pqTraceReaction::start())
745 void PVGUI_Module::startTrace()
747 vtkSMSessionProxyManager* pxm = pqActiveObjects::instance().activeServer()->proxyManager();
749 vtkSmartPointer<vtkSMProxy> proxy;
750 proxy.TakeReference( pxm->NewProxy( "pythontracing", "PythonTraceOptions" ) );
752 vtkNew<vtkSMParaViewPipelineController> controller;
753 controller->InitializeProxy( proxy );
755 vtkSMTrace* trace = vtkSMTrace::StartTrace();
757 // Set manually the properties entered via the dialog box poping-up when requiring
758 // a trace start in PV4.2 (trace options)
759 SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr();
760 int type = aResourceMgr->integerValue( PARAVIS_MODULE_NAME, "tracestate_type", 2 );
761 trace->SetPropertiesToTraceOnCreate( type );
762 trace->SetFullyTraceSupplementalProxies( false );
767 \brief Stops Python trace.
769 void PVGUI_Module::stopTrace()
771 vtkSMTrace::StopTrace();
775 \brief Execute a Python script.
777 void PVGUI_Module::executeScript( const char* script )
780 pqPythonManager* manager = qobject_cast<pqPythonManager*>(
781 pqApplicationCore::instance()->manager( "PYTHON_MANAGER" ) );
783 pqPythonDialog* pyDiag = manager->pythonShellDialog();
785 pyDiag->runString(script);
792 // * Debug function printing out the given interpreter's execution context
794 //void printInterpContext(PyInterp_Interp * interp )
796 // // Extract __smtraceString from interpreter's context
797 // const PyObject* ctxt = interp->getExecutionContext();
799 // PyObject* lst = PyDict_Keys((PyObject *)ctxt);
800 // Py_ssize_t siz = PyList_GET_SIZE(lst);
801 // for (Py_ssize_t i = 0; i < siz; i++)
803 // PyObject * elem = PyList_GetItem(lst, i);
804 // if (PyString_Check(elem))
806 // std::cout << "At pos:" << i << ", " << Py_EncodeLocale(PyUnicode_AS_UNICODE(elem), NULL) << std::endl;
809 // std::cout << "At pos:" << i << ", not a string!" << std::endl;
815 \brief Returns trace string
817 QString PVGUI_Module::getTraceString()
819 QString traceString = "";
821 static const QString replaceStr( "paraview.simple" );
822 std::stringstream nl;
823 nl << std::endl; // surely there is some Qt trick to do that in a portable way??
824 QString end_line( nl.str().c_str() );
826 vtkSMTrace* tracer = vtkSMTrace::GetActiveTracer();
828 traceString = tracer->GetCurrentTrace();
829 // 'import pvsimple' is necessary to fix the first call to DisableFirstRenderCamera in the paraview trace
830 // 'ShowParaviewView()' ensure there is an opened viewing window (otherwise SEGFAULT!)
831 traceString = "import pvsimple" + end_line +
832 "pvsimple.ShowParaviewView()" + end_line + traceString;
834 // Replace import "paraview.simple" by "pvsimple"
835 if ( !traceString.isEmpty() ) {
836 int aPos = traceString.indexOf( replaceStr );
837 while ( aPos != -1 ) {
838 traceString = traceString.replace( aPos, replaceStr.length(), "pvsimple" );
839 aPos = traceString.indexOf( replaceStr, aPos );
844 // Save camera position to, which is no longer output by the tracer ...
846 vtkPythonScopeGilEnsurer psge;
847 PyObject * mods(PySys_GetObject(const_cast<char*>("modules")));
848 PyObject * trace_mod(PyDict_GetItemString(mods, "paraview.smtrace")); // module was already (really) imported by vtkSMTrace
849 if (PyModule_Check(trace_mod)) {
850 vtkSmartPyObject save_cam(PyObject_GetAttrString(trace_mod, const_cast<char*>("SaveCameras")));
851 vtkSmartPyObject camera_trace(PyObject_CallMethod(save_cam, const_cast<char*>("get_trace"), NULL));
852 // Convert to a single string
853 vtkSmartPyObject ret(PyUnicode_FromUnicode(Py_DecodeLocale(end_line.toStdString().c_str(), NULL), end_line.size()));
854 vtkSmartPyObject final_string(PyObject_CallMethod(ret, const_cast<char*>("join"),
855 const_cast<char*>("O"), (PyObject*)camera_trace));
856 if (PyUnicode_CheckExact(final_string))
858 QString camera_qs(Py_EncodeLocale(PyUnicode_AS_UNICODE(final_string.GetPointer()), NULL)); // deep copy
859 traceString = traceString + end_line + end_line + QString("#### saving camera placements for all active views")
860 + end_line + end_line + camera_qs + end_line;
869 \brief Saves trace string to disk file
871 void PVGUI_Module::saveTrace( const char* theName )
873 QFile file( theName );
874 if ( !file.open( QIODevice::WriteOnly | QIODevice::Text ) ) {
875 MESSAGE( "Could not open file:" << theName );
878 QTextStream out( &file );
879 out << getTraceString();
884 \brief Saves ParaView state to a disk file
886 void PVGUI_Module::saveParaviewState( const QString& theFileName )
888 pqApplicationCore::instance()->saveState( theFileName.toStdString().c_str() );
892 \brief Delete all objects for Paraview Pipeline Browser
894 void PVGUI_Module::clearParaviewState()
896 QAction* deleteAllAction = action( DeleteAllId );
897 if ( deleteAllAction ) {
898 deleteAllAction->activate( QAction::Trigger );
903 \brief Restores ParaView state from a disk file
905 void PVGUI_Module::loadParaviewState( const QString& theFileName )
907 pqApplicationCore::instance()->loadState( theFileName.toStdString().c_str(), getActiveServer() );
911 \brief Returns current active ParaView server
913 pqServer* PVGUI_Module::getActiveServer()
915 return pqApplicationCore::instance()->getActiveServer();
920 \brief Creates PARAVIS preferences panel.
922 void PVGUI_Module::createPreferences()
924 QList<QVariant> aIndices;
925 QStringList aStrings;
927 // Paraview settings tab
928 int aParaViewSettingsTab = addPreference( tr( "TIT_PVIEWSETTINGS" ) );
930 setPreferenceProperty(aParaViewSettingsTab, "stretch", false );
931 int aPanel = addPreference( QString(), aParaViewSettingsTab,
932 LightApp_Preferences::UserDefined, PARAVIS_MODULE_NAME, "" );
934 setPreferenceProperty( aPanel, "content", (qint64)( new PVGUI_ParaViewSettingsPane( 0, getApp() ) ) );
936 // Paravis settings tab
937 int aParaVisSettingsTab = addPreference( tr( "TIT_PVISSETTINGS" ) );
939 addPreference( tr( "PREF_NO_EXT_PVSERVER" ), aParaVisSettingsTab,
940 LightApp_Preferences::Bool, PARAVIS_MODULE_NAME, "no_ext_pv_server" );
942 int aSaveType = addPreference( tr( "PREF_SAVE_TYPE_LBL" ), aParaVisSettingsTab,
943 LightApp_Preferences::Selector,
944 PARAVIS_MODULE_NAME, "savestate_type" );
948 aIndices << 0 << 1 << 2;
949 aStrings << tr("PREF_SAVE_TYPE_0") << tr("PREF_SAVE_TYPE_1") << tr("PREF_SAVE_TYPE_2");
950 setPreferenceProperty( aSaveType, "strings", aStrings );
951 setPreferenceProperty( aSaveType, "indexes", aIndices );
953 // ... "Language" group <<start>>
954 int traceGroup = addPreference( tr( "PREF_GROUP_TRACE" ), aParaVisSettingsTab );
956 int stopTrace = addPreference( tr( "PREF_STOP_TRACE" ), traceGroup,
957 LightApp_Preferences::Bool, PARAVIS_MODULE_NAME, "stop_trace" );
958 setPreferenceProperty( stopTrace, "restart", true );
960 int aTraceType = addPreference( tr( "PREF_TRACE_TYPE_LBL" ), traceGroup,
961 LightApp_Preferences::Selector,
962 PARAVIS_MODULE_NAME, "tracestate_type" );
965 aIndices << 0 << 1 << 2;
966 aStrings << tr("PREF_TRACE_TYPE_0") << tr("PREF_TRACE_TYPE_1") << tr("PREF_TRACE_TYPE_2");
967 setPreferenceProperty( aTraceType, "strings", aStrings );
968 setPreferenceProperty( aTraceType, "indexes", aIndices );
969 setPreferenceProperty( aTraceType, "restart", true );
973 \brief. Show ParaView python trace.
975 void PVGUI_Module::onShowTrace()
977 if (!myTraceWindow) {
978 myTraceWindow = new pqPythonScriptEditor(getApp()->desktop());
980 myTraceWindow->setText(getTraceString());
981 myTraceWindow->show();
982 myTraceWindow->raise();
983 myTraceWindow->activateWindow();
988 \brief. Re-initialize ParaView python trace.
990 void PVGUI_Module::onRestartTrace()
997 \brief. Close ParaView python trace.
999 void PVGUI_Module::onStopTrace()
1004 \brief Called when view manager is added
1006 void PVGUI_Module::onViewManagerAdded( SUIT_ViewManager* vm )
1008 if ( PVViewer_ViewManager* pvvm = dynamic_cast<PVViewer_ViewManager*>( vm ) ) {
1009 connect( pvvm, SIGNAL( viewCreated( SUIT_ViewWindow* ) ),
1010 this, SLOT( onPVViewCreated( SUIT_ViewWindow* ) ) );
1011 connect( pvvm, SIGNAL( deleteView( SUIT_ViewWindow* ) ),
1012 this, SLOT( onPVViewDelete( SUIT_ViewWindow* ) ) );
1017 \brief Called when view manager is removed
1019 void PVGUI_Module::onViewManagerRemoved( SUIT_ViewManager* vm )
1021 if ( PVViewer_ViewManager* pvvm = dynamic_cast<PVViewer_ViewManager*>( vm ) )
1022 disconnect( pvvm, SIGNAL( viewCreated( SUIT_ViewWindow* ) ),
1023 this, SLOT( onPVViewCreated( SUIT_ViewWindow* ) ) );
1027 \brief Show toolbars at \a vw PV view window creating when PARAVIS is active.
1029 void PVGUI_Module::onPVViewCreated( SUIT_ViewWindow* vw )
1031 myGuiElements->setToolBarVisible( true );
1032 restoreDockWidgetsState();
1036 \brief Save toolbars state at \a view view closing.
1038 void PVGUI_Module::onPVViewDelete( SUIT_ViewWindow* view )
1040 if ( dynamic_cast<PVViewer_ViewWindow*>( view ) )
1041 saveDockWidgetsState( false );
1045 \fn CAM_Module* createModule();
1046 \brief Export module instance (factory function).
1047 \return new created instance of the module
1051 #define PVGUI_EXPORT __declspec(dllexport)
1053 #define PVGUI_EXPORT
1059 PVGUI_EXPORT CAM_Module* createModule() {
1060 return new PVGUI_Module();
1063 PVGUI_EXPORT char* getModuleVersion() {
1064 return (char*)PARAVIS_VERSION_STR;