X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FPVGUI%2FPVGUI_Module.cxx;h=6fa52dbe326922aa6be2150da2569db368740308;hb=4cde1a359421d29a442b21c452e7b89bba8f96b7;hp=c7a6f540ecdb7abccf21b4c175322004543d5c08;hpb=cac67faeceee11791fcf15dff772c86dd3a53ad8;p=modules%2Fparavis.git diff --git a/src/PVGUI/PVGUI_Module.cxx b/src/PVGUI/PVGUI_Module.cxx index c7a6f540..6fa52dbe 100644 --- a/src/PVGUI/PVGUI_Module.cxx +++ b/src/PVGUI/PVGUI_Module.cxx @@ -1,6 +1,6 @@ // PARAVIS : ParaView wrapper SALOME module // -// Copyright (C) 2010-2014 CEA/DEN, EDF R&D +// Copyright (C) 2010-2015 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -20,29 +20,27 @@ // // File : PVGUI_Module.cxx +#define PARAVIS_MODULE_NAME "PARAVIS" + #include // E.A. must be included before Python.h to fix compilation on windows #ifdef HAVE_FINITE #undef HAVE_FINITE // VSR: avoid compilation warning on Linux : "HAVE_FINITE" redefined #endif #include // Python first -#include "PVGUI_Module.h" - -#ifdef PARAVIS_WITH_FULL_CORBA -# include "PARAVIS_Gen_i.hh" -#endif -#include CORBA_SERVER_HEADER(SALOME_ModuleCatalog) -#include CORBA_SERVER_HEADER(SALOMEDS) +#include "PVGUI_Module.h" -#include "PVGUI_ViewModel.h" -#include "PVGUI_ViewManager.h" -#include "PVGUI_ViewWindow.h" -#include "PVGUI_Tools.h" +#include "PVViewer_ViewManager.h" +#include "PVViewer_Core.h" +#include "PVViewer_ViewWindow.h" +#include "PVViewer_ViewModel.h" #include "PVGUI_ParaViewSettingsPane.h" -#include "PVGUI_OutputWindowAdapter.h" -#include "PVGUI_Behaviors.h" +#include "PVViewer_GUIElements.h" +#include "PVServer_ServiceWrapper.h" +#include "PVGUI_DataModel.h" // SALOME Includes +#include #include #include #include @@ -51,17 +49,11 @@ #include #include -#include -#include - #include #include -#include -#include +#include +#include #include -#include -#include -#include #include #include @@ -104,10 +96,10 @@ #include #include #include +#include #include -//#include -#include +#include #include #include #include @@ -127,70 +119,24 @@ #include #include #include -#include +#include +#include +#include +#include +#include //---------------------------------------------------------------------------- PVGUI_Module* ParavisModule = 0; /*! \mainpage + This is the doxygen documentation of the ParaVis module. + If you are looking for general information about the structure of the module, you should + take a look at the Sphinx documentation first. -

Building and installing PARAVIS

- As any other SALOME module, PARAVIS requires PARAVIS_ROOT_DIR environment variable to be set to PARAVIS - installation directory. - Other variables needed for correct detection of ParaView location: - \li PVHOME - points at the ParaView installation directory tree - \li PVVERSION - number of ParaView version - - It also requires common SALOME environment including GUI_ROOT_DIR and other prerequsites. - - - PARAVIS module can be launched using the following commands: - \li Full SALOME configuration - \code - runSalome --modules="PARAVIS" - \endcode - -

ParaView GUI integration

-

ParaView GUI integration overview

- - The main idea is to reuse ParaView GUI internal logic as much as possible, providing a layer - between it and SALOME GUI that hides the following SALOME GUI implementation details from ParaView: - - \li SALOME GUI executable and Qt event loop - \li SALOME GUI desktop - \li Dock windows areas - \li SALOME menu and toolbar managers - - Major part of the integration is implemented in PVGUI_Module class. - -

ParaView client initalization

- - ParaView client initalization is performed when an instance of PVGUI_Module class has been created - and \link PVGUI_Module::initialize() PVGUI_Module::initialize()\endlink method is called by SALOME GUI. - The actual client start-up is done in \link PVGUI_Module::pvInit() PVGUI_Module::pvInit()\endlink method. - - -

Multi-view manager

- - SALOME GUI requires that each kind of view be implemnted with help of (at least) three classes. For ParaView multi-view manager - these are: - - \li PVGUI_ViewManager - view manager class - \li PVGUI_Viewer - view model class - \li PVGUI_ViewWindow - view window class that acts as a parent for %pqViewManager - - Single instances of PVGUI_ViewManager and PVGUI_ViewWindow classes are created by \link PVGUI_Module::showView() - PVGUI_Module::showView()\endlink method upon the first PARAVIS module activation. The same method hides the multi-view manager - when the module is deactivated (the user switches to another module or a study is closed). - A special trick is used to make PVGUI_ViewWindow the parent of %pqViewManager widget. It is created initally by %pqMainWindowCore - with the desktop as a parent, so when it is shown PVGUI_ViewWindow instance is passed to its setParent() method. In - \link PVGUI_ViewWindow::~PVGUI_ViewWindow() PVGUI_ViewWindow::~PVGUI_ViewWindow()\endlink the parent is nullified to avoid deletion - of %pqViewManager widget that would break %pqMainWindowCore class. - -

ParaView plugins

- ParaView server and client plugins are managed by %pqMainWindowCore slots that has full access to PARAVIS menus and toolbars. - As a result they appears automatically in PARAVIS menus and toolbars if loaded successfully. + The integration of ParaView into SALOME is split in two parts: + \li the PVViewer in the GUI module (folder *src/PVViewer*) + \li the ParaVis module itself (the pages you are currently browsing) */ /*! @@ -200,7 +146,9 @@ PVGUI_Module* ParavisModule = 0; */ /*! - Clean up function; used to stop ParaView progress events when + \brief Clean up function + + Used to stop ParaView progress events when exception is caught by global exception handler. */ void paravisCleanUp() @@ -215,18 +163,15 @@ void paravisCleanUp() \brief Constructor. Sets the default name for the module. */ PVGUI_Module::PVGUI_Module() - : SalomeApp_Module( "PARAVIS" ), - mySelectionControlsTb( -1 ), + : LightApp_Module( PARAVIS_MODULE_NAME ), mySourcesMenuId( -1 ), myFiltersMenuId( -1 ), myMacrosMenuId(-1), - myToolbarsMenuId(-1), myRecentMenuId(-1), myOldMsgHandler(0), myTraceWindow(0), - myStateCounter(0), myInitTimer(0), - myPushTraceTimer(0) + myGuiElements(0) { #ifdef HAS_PV_DOC Q_INIT_RESOURCE( PVGUI ); @@ -253,22 +198,36 @@ PVGUI_Module::PVGUI_Module() */ PVGUI_Module::~PVGUI_Module() { - if (myPushTraceTimer) - delete myPushTraceTimer; if (myInitTimer) delete myInitTimer; - // Disconnect from server - pqServer* server = pqActiveObjects::instance().activeServer(); - if (server && server->isRemote()) - { - MESSAGE("~PVGUI_Module(): Disconnecting from remote server ..."); - pqServerDisconnectReaction::disconnectFromServer(); - } } -PARAVIS_ORB::PARAVIS_Gen_var PVGUI_Module::GetEngine() +/*! + \brief Retrieve the PVSERVER CORBA engine. + This uses the Python wrapper provided + by the PVViewer code in GUI (class PVViewer_EngineWrapper). + \sa GetCPPEngine() +*/ +PVServer_ServiceWrapper* PVGUI_Module::GetEngine() { - return PVGUI_ViewerModel::GetEngine(); + return PVServer_ServiceWrapper::GetInstance(); +} + +/*! + \brief Create data model. + \return module specific data model +*/ +CAM_DataModel* PVGUI_Module::createDataModel() +{ + return new PVGUI_DataModel( this ); +} + +/*! + \brief Get the ParaView application singleton. +*/ +pqPVApplicationCore* PVGUI_Module::GetPVApplication() +{ + return PVViewer_Core::GetPVApplication(); } /*! @@ -277,12 +236,7 @@ PARAVIS_ORB::PARAVIS_Gen_var PVGUI_Module::GetEngine() */ void PVGUI_Module::initialize( CAM_Application* app ) { - SalomeApp_Module::initialize( app ); - - // Create ParaViS actions - createActions(); - // Create ParaViS menus - createMenus(); + LightApp_Module::initialize( app ); // Uncomment to debug ParaView initialization // "aa" used instead of "i" as GDB doesn't like "i" variables :) @@ -292,29 +246,33 @@ void PVGUI_Module::initialize( CAM_Application* app ) aa = aa; } */ - - // Initialize ParaView client - pvInit(); - // Create GUI elements (menus, toolbars, dock widgets) - SalomeApp_Application* anApp = getApp(); + LightApp_Application* anApp = getApp(); SUIT_Desktop* aDesktop = anApp->desktop(); // Remember current state of desktop toolbars QList foreignToolbars = aDesktop->findChildren(); + // Initialize ParaView client and associated behaviors + // and connect to externally launched pvserver + PVViewer_Core::ParaviewInitApp(aDesktop, anApp->logWindow()); + myGuiElements = PVViewer_GUIElements::GetInstance(aDesktop); + + // [ABN]: careful with the order of the GUI element creation, the loading of the configuration + // and the connection to the server. This order is very sensitive if one wants to make + // sure all menus, etc ... are correctly populated. + // Reference points are: ParaViewMainWindow.cxx and branded_paraview_initializer.cxx.in setupDockWidgets(); pvCreateActions(); - pvCreateToolBars(); pvCreateMenus(); + pvCreateToolBars(); + + PVViewer_Core::ParaviewInitBehaviors(true, aDesktop); QList activeDocks = aDesktop->findChildren(); QList activeMenus = aDesktop->findChildren(); - PVGUI_Behaviors * behav = new PVGUI_Behaviors(this); - behav->instanciateAllBehaviors(aDesktop); - // Setup quick-launch shortcuts. QShortcut *ctrlSpace = new QShortcut(Qt::CTRL + Qt::Key_Space, aDesktop); QObject::connect(ctrlSpace, SIGNAL(activated()), @@ -342,25 +300,31 @@ void PVGUI_Module::initialize( CAM_Application* app ) // } // } - SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); - QString aPath = resMgr->stringValue("resources", "PARAVIS", QString()); - if (!aPath.isNull()) { - MyCoreApp->loadConfiguration(aPath + QDir::separator() + "ParaViewFilters.xml"); - MyCoreApp->loadConfiguration(aPath + QDir::separator() + "ParaViewReaders.xml"); - MyCoreApp->loadConfiguration(aPath + QDir::separator() + "ParaViewSources.xml"); - MyCoreApp->loadConfiguration(aPath + QDir::separator() + "ParaViewWriters.xml"); - } - - // Force creation of the PARAVIS engine - GetEngine(); + // Connect after toolbar creation, etc ... as some activations of the toolbars is triggered + // by the ServerConnection event: + const QString configPath(PVViewer_ViewManager::GetPVConfigPath()); + PVViewer_Core::ParaviewLoadConfigurations(configPath, true); + PVViewer_ViewManager::ConnectToExternalPVServer(aDesktop); updateObjBrowser(); // Find created toolbars QCoreApplication::processEvents(); + // process PVViewer toolbars (might be added by PVViewer created BEFORE activating ParaVis) + QList pvToolbars = myGuiElements->getToolbars(); + foreach(QToolBar* aBar, pvToolbars) { + if (!myToolbars.contains(aBar)) { + myToolbars[aBar] = true; + myToolbarBreaks[aBar] = false; + aBar->setVisible(false); + aBar->toggleViewAction()->setVisible(false); + } + } + + // process other toolbars (possibly added by Paraview) QList allToolbars = aDesktop->findChildren(); foreach(QToolBar* aBar, allToolbars) { - if (!foreignToolbars.contains(aBar)) { + if (!foreignToolbars.contains(aBar) && !myToolbars.contains(aBar)) { myToolbars[aBar] = true; myToolbarBreaks[aBar] = false; aBar->setVisible(false); @@ -371,22 +335,15 @@ void PVGUI_Module::initialize( CAM_Application* app ) updateMacros(); SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr(); - bool isStop = aResourceMgr->booleanValue( "PARAVIS", "stop_trace", false ); + bool isStop = aResourceMgr->booleanValue( PARAVIS_MODULE_NAME, "stop_trace", false ); if(!isStop) { // Start a timer to schedule asap: - // - the connection to the server // - the trace start myInitTimer = new QTimer(aDesktop); QObject::connect(myInitTimer, SIGNAL(timeout()), this, SLOT(onInitTimer()) ); myInitTimer->setSingleShot(true); myInitTimer->start(0); - - // Another timer to regularly push the trace onto the engine: - myPushTraceTimer = new QTimer(aDesktop); - QObject::connect(myPushTraceTimer, SIGNAL(timeout()), this, SLOT(onPushTraceTimer()) ); - myPushTraceTimer->setSingleShot(false); - myPushTraceTimer->start(500); } this->VTKConnect = vtkEventQtSlotConnect::New(); @@ -404,34 +361,43 @@ void PVGUI_Module::initialize( CAM_Application* app ) } } } + connect( application(), SIGNAL( appClosed() ), this, SLOT( onStopTrace() ) ); } +/*! + * \brief Slot called when the progress bar starts. + */ void PVGUI_Module::onStartProgress() { - QApplication::setOverrideCursor(Qt::WaitCursor); + // VSR 19/03/2015, issue 0023025 + // next line is commented: it is bad idea to show wait cursor on ANY vtk event + // moreover, it does not work when running pvserver with --multi-client mode + //QApplication::setOverrideCursor(Qt::WaitCursor); } +/*! + * \brief Slot called when the progress bar is done. + */ void PVGUI_Module::onEndProgress() { - QApplication::restoreOverrideCursor(); + // VSR 19/03/2015, issue 0023025 + // next line is commented: it is bad idea to show wait cursor on ANY vtk event + // moreover, it does not work when running pvserver with --multi-client mode + //QApplication::restoreOverrideCursor(); } void PVGUI_Module::onDataRepresentationUpdated() { - SalomeApp_Study* activeStudy = dynamic_cast(application()->activeStudy()); + LightApp_Study* activeStudy = dynamic_cast(application()->activeStudy()); if(!activeStudy) return; activeStudy->Modified(); } /*! - \brief Initialisation timer event - fired only once, after the GUI loop is ready. - See creation in initialize(). + \brief Initialisation timer event - Starts up the Python trace */ void PVGUI_Module::onInitTimer() { -#ifndef PARAVIS_WITH_FULL_CORBA - connectToExternalPVServer(); -#endif startTrace(); } @@ -456,6 +422,9 @@ QStringList PVGUI_Module::getEmbeddedMacrosList() return aFullPathSourceFiles; } +/*! + \brief Update the list of embedded macros +*/ void PVGUI_Module::updateMacros() { pqPythonManager* aPythonManager = pqPVApplicationCore::instance()->pythonManager(); @@ -476,7 +445,9 @@ void PVGUI_Module::updateMacros() void PVGUI_Module::windows( QMap& m ) const { m.insert( LightApp_Application::WT_ObjectBrowser, Qt::LeftDockWidgetArea ); +#ifndef DISABLE_PYCONSOLE m.insert( LightApp_Application::WT_PyConsole, Qt::BottomDockWidgetArea ); +#endif // ParaView diagnostic output redirected here m.insert( LightApp_Application::WT_LogWindow, Qt::BottomDockWidgetArea ); } @@ -486,23 +457,26 @@ void PVGUI_Module::windows( QMap& m ) const */ void PVGUI_Module::showView( bool toShow ) { - PVGUI_ViewManager - SalomeApp_Application* anApp = getApp(); - PVGUI_ViewManager* viewMgr = - dynamic_cast( anApp->getViewManager( PVGUI_Viewer::Type(), false ) ); + // VSR: TODO: all below is not needed, if we use standard approach + // that consists in implementing viewManagers() function properly + // This should be done after we decide what to do with Log window. + LightApp_Application* anApp = getApp(); + PVViewer_ViewManager* viewMgr = + dynamic_cast( anApp->getViewManager( PVViewer_Viewer::Type(), false ) ); if ( !viewMgr ) { - viewMgr = new PVGUI_ViewManager( anApp->activeStudy(), anApp->desktop() ); + viewMgr = new PVViewer_ViewManager( anApp->activeStudy(), anApp->desktop(), anApp->logWindow() ); anApp->addViewManager( viewMgr ); connect( viewMgr, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ), anApp, SLOT( onCloseView( SUIT_ViewManager* ) ) ); } - PVGUI_ViewWindow* pvWnd = dynamic_cast( viewMgr->getActiveView() ); + PVViewer_ViewWindow* pvWnd = dynamic_cast( viewMgr->getActiveView() ); if ( !pvWnd ) { - pvWnd = dynamic_cast( viewMgr->createViewWindow() ); + pvWnd = dynamic_cast( viewMgr->createViewWindow() ); + // this also connects to the pvserver and instantiates relevant PV behaviors } - pvWnd->setShown( toShow ); + pvWnd->setVisible( toShow ); if ( toShow ) pvWnd->setFocus(); } @@ -514,7 +488,6 @@ void PVGUI_Module::showHelpForProxy( const QString& groupname, const QString& pr pqHelpReaction::showProxyHelp(groupname, proxyname); } - /*! \brief Slot to show the waiting state. */ @@ -540,7 +513,10 @@ void PVGUI_Module::endWaitCursor() { QApplication::restoreOverrideCursor(); } - +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) +/*! + \brief Handler method for the output of messages. +*/ static void ParavisMessageOutput(QtMsgType type, const char *msg) { switch(type) @@ -559,7 +535,29 @@ static void ParavisMessageOutput(QtMsgType type, const char *msg) break; } } - +#else +/*! + \brief Handler method for the output of messages. +*/ +static void ParavisMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg) +{ + switch(type) + { + case QtDebugMsg: + vtkOutputWindow::GetInstance()->DisplayText(msg.toLatin1().constData()); + break; + case QtWarningMsg: + vtkOutputWindow::GetInstance()->DisplayErrorText(msg.toLatin1().constData()); + break; + case QtCriticalMsg: + vtkOutputWindow::GetInstance()->DisplayErrorText(msg.toLatin1().constData()); + break; + case QtFatalMsg: + vtkOutputWindow::GetInstance()->DisplayErrorText(msg.toLatin1().constData()); + break; + } +} +#endif /*! \brief Activate module. \param study current study @@ -568,20 +566,31 @@ static void ParavisMessageOutput(QtMsgType type, const char *msg) */ bool PVGUI_Module::activateModule( SUIT_Study* study ) { +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) myOldMsgHandler = qInstallMsgHandler(ParavisMessageOutput); - +#else + myOldMsgHandler = qInstallMessageHandler(ParavisMessageOutput); +#endif SUIT_ExceptionHandler::addCleanUpRoutine( paravisCleanUp ); storeCommonWindowsState(); - bool isDone = SalomeApp_Module::activateModule( study ); + bool isDone = LightApp_Module::activateModule( study ); if ( !isDone ) return false; showView( true ); if ( mySourcesMenuId != -1 ) menuMgr()->show(mySourcesMenuId); if ( myFiltersMenuId != -1 ) menuMgr()->show(myFiltersMenuId); - if ( myFiltersMenuId != -1 ) menuMgr()->show(myMacrosMenuId); - if ( myFiltersMenuId != -1 ) menuMgr()->show(myToolbarsMenuId); + if ( myMacrosMenuId != -1 ) menuMgr()->show(myMacrosMenuId); + + // Update the various menus with the content pre-loaded in myGuiElements +// QMenu* srcMenu = menuMgr()->findMenu( mySourcesMenuId ); +// myGuiElements->updateSourcesMenu(srcMenu); +// QMenu* filtMenu = menuMgr()->findMenu( myFiltersMenuId ); +// myGuiElements->updateFiltersMenu(filtMenu); +// QMenu* macMenu = menuMgr()->findMenu( myMacrosMenuId ); +// myGuiElements->updateMacrosMenu(macMenu); + setMenuShown( true ); setToolShown( true ); @@ -605,9 +614,7 @@ bool PVGUI_Module::activateModule( SUIT_Study* study ) } if ( myRecentMenuId != -1 ) menuMgr()->show(myRecentMenuId); - -// ClientFindOrCreateParavisComponent(PARAVIS::GetCStudy(this)); - + return isDone; } @@ -648,13 +655,11 @@ bool PVGUI_Module::deactivateModule( SUIT_Study* study ) /*if (pqImplementation::helpWindow) { pqImplementation::helpWindow->hide(); }*/ - showView( false ); // hide menus menuMgr()->hide(myRecentMenuId); menuMgr()->hide(mySourcesMenuId); menuMgr()->hide(myFiltersMenuId); menuMgr()->hide(myMacrosMenuId); - menuMgr()->hide(myToolbarsMenuId); setMenuShown( false ); setToolShown( false ); @@ -663,11 +668,14 @@ bool PVGUI_Module::deactivateModule( SUIT_Study* study ) SUIT_ExceptionHandler::removeCleanUpRoutine( paravisCleanUp ); if (myOldMsgHandler) +#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) qInstallMsgHandler(myOldMsgHandler); - +#else + qInstallMessageHandler(myOldMsgHandler); +#endif restoreCommonWindowsState(); - return SalomeApp_Module::deactivateModule( study ); + return LightApp_Module::deactivateModule( study ); } @@ -681,29 +689,10 @@ bool PVGUI_Module::deactivateModule( SUIT_Study* study ) */ void PVGUI_Module::onApplicationClosed( SUIT_Application* theApp ) { - pqApplicationCore::instance()->settings()->sync(); - int aAppsNb = SUIT_Session::session()->applications().size(); - if (aAppsNb == 1) { - deleteTemporaryFiles(); - MyCoreApp->deleteLater(); - } + PVViewer_Core::ParaviewCleanup(); CAM_Module::onApplicationClosed(theApp); } - -/*! - \brief Deletes temporary files created during import operation from VISU -*/ -void PVGUI_Module::deleteTemporaryFiles() -{ - foreach(QString aFile, myTemporaryFiles) { - if (QFile::exists(aFile)) { - QFile::remove(aFile); - } - } -} - - /*! \brief Called when study is closed. @@ -713,101 +702,73 @@ void PVGUI_Module::deleteTemporaryFiles() */ void PVGUI_Module::studyClosed(SUIT_Study* study) { + showView(false); // VSR: this seems to be not needed (all views are automatically closed) clearParaviewState(); + //Re-start trace + onRestartTrace(); - SalomeApp_Module::studyClosed(study); -} - -/*! - \brief Called when study is opened. -*/ -void PVGUI_Module::onModelOpened() -{ - _PTR(Study) studyDS = PARAVIS::GetCStudy(this); - if(!studyDS) { - return; - } - - _PTR(SComponent) paravisComp = - studyDS->FindComponent(GetEngine()->ComponentDataType()); - if(!paravisComp) { - return; - } - - _PTR(ChildIterator) anIter(studyDS->NewChildIterator(paravisComp)); - for (; anIter->More(); anIter->Next()) { - _PTR(SObject) aSObj = anIter->Value(); - _PTR(GenericAttribute) anAttr; - if (!aSObj->FindAttribute(anAttr, "AttributeLocalID")) { - continue; - } - _PTR(AttributeLocalID) anID(anAttr); - if (anID->Value() == PVSTATEID) { - myStateCounter++; - } - } -} - -/*! - \brief Returns IOR of current engine -*/ -QString PVGUI_Module::engineIOR() const -{ - CORBA::String_var anIOR = GetEngine()->GetIOR(); - return QString(anIOR.in()); + LightApp_Module::studyClosed(study); } /*! \brief Open file of format supported by ParaView */ -void PVGUI_Module::openFile(const char* theName) +void PVGUI_Module::openFile( const char* theName ) { QStringList aFiles; - aFiles<proxyManager(); vtkSmartPointer proxy; - proxy.TakeReference(pxm->NewProxy("pythontracing", "PythonTraceOptions")); - if (proxy) - { - vtkNew controller; - controller->InitializeProxy(proxy); - } + proxy.TakeReference( pxm->NewProxy( "pythontracing", "PythonTraceOptions" ) ); + if ( proxy ) { + vtkNew controller; + controller->InitializeProxy( proxy ); + } vtkSMTrace* trace = vtkSMTrace::StartTrace(); - if (proxy) - { - // Set manually the properties entered via the dialog box poping-up when requiring - // a trace start in PV4.2 (trace options) - trace->SetPropertiesToTraceOnCreate(vtkSMTrace::RECORD_USER_MODIFIED_PROPERTIES); - trace->SetFullyTraceSupplementalProxies(false); - } + if ( proxy ) { + // Set manually the properties entered via the dialog box poping-up when requiring + // a trace start in PV4.2 (trace options) + SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr(); + int type = aResourceMgr->integerValue( PARAVIS_MODULE_NAME, "tracestate_type", 2 ); + trace->SetPropertiesToTraceOnCreate( type ); + trace->SetFullyTraceSupplementalProxies( false ); + } } +/*! + \brief Stops Python trace. +*/ void PVGUI_Module::stopTrace() { vtkSMTrace::StopTrace(); } -void PVGUI_Module::executeScript(const char *script) +/*! + \brief Execute a Python script. +*/ +void PVGUI_Module::executeScript( const char* script ) { #ifndef WNT pqPythonManager* manager = qobject_cast( - pqApplicationCore::instance()->manager("PYTHON_MANAGER")); - if (manager) { + pqApplicationCore::instance()->manager( "PYTHON_MANAGER" ) ); + if ( manager ) { pqPythonDialog* pyDiag = manager->pythonShellDialog(); - if (pyDiag) { + if ( pyDiag ) { pyDiag->runString(script); - } } + } #endif } @@ -837,44 +798,68 @@ void PVGUI_Module::executeScript(const char *script) /*! \brief Returns trace string */ -static const QString MYReplaceStr("paraview.simple"); -static const QString MYReplaceImportStr("except: from pvsimple import *"); QString PVGUI_Module::getTraceString() { - vtkSMTrace *tracer = vtkSMTrace::GetActiveTracer(); - if (!tracer) // trace is not started - return QString(""); - - QString traceString(tracer->GetCurrentTrace()); - - // Replace import "paraview.simple" by "pvsimple" - if ((!traceString.isNull()) && traceString.length() != 0) { - int aPos = traceString.indexOf(MYReplaceStr); - while (aPos != -1) { - traceString = traceString.replace(aPos, MYReplaceStr.length(), "pvsimple"); - aPos = traceString.indexOf(MYReplaceStr, aPos); - } - int aImportPos = traceString.indexOf(MYReplaceImportStr); - if(aImportPos != -1) - { - traceString = traceString.replace(aImportPos, MYReplaceImportStr.length(), "except:\n import pvsimple\n from pvsimple import *"); + QString traceString = ""; + + static const QString replaceStr( "paraview.simple" ); + std::stringstream nl; + nl << std::endl; // surely there is some Qt trick to do that in a portable way?? + QString end_line( nl.str().c_str() ); + + vtkSMTrace* tracer = vtkSMTrace::GetActiveTracer(); + if ( tracer ) { + traceString = tracer->GetCurrentTrace(); + // 'import pvsimple' is necessary to fix the first call to DisableFirstRenderCamera in the paraview trace + // 'ShowParaviewView()' ensure there is an opened viewing window (otherwise SEGFAULT!) + traceString = "import pvsimple" + end_line + + "pvsimple.ShowParaviewView()" + end_line + traceString; + + // Replace import "paraview.simple" by "pvsimple" + if ( !traceString.isEmpty() ) { + int aPos = traceString.indexOf( replaceStr ); + while ( aPos != -1 ) { + traceString = traceString.replace( aPos, replaceStr.length(), "pvsimple" ); + aPos = traceString.indexOf( replaceStr, aPos ); } + } } + // Save camera position to, which is no longer output by the tracer ... + { + vtkPythonScopeGilEnsurer psge; + PyObject * mods(PySys_GetObject(const_cast("modules"))); + PyObject * trace_mod(PyDict_GetItemString(mods, "paraview.smtrace")); // module was already (really) imported by vtkSMTrace + if (PyModule_Check(trace_mod)) { + vtkSmartPyObject save_cam(PyObject_GetAttrString(trace_mod, const_cast("SaveCameras"))); + vtkSmartPyObject camera_trace(PyObject_CallMethod(save_cam, const_cast("get_trace"), NULL)); + // Convert to a single string + vtkSmartPyObject ret(PyString_FromString(end_line.toStdString().c_str())); + vtkSmartPyObject final_string(PyObject_CallMethod(ret, const_cast("join"), + const_cast("O"), (PyObject*)camera_trace)); + if (PyString_CheckExact(final_string)) + { + QString camera_qs(PyString_AsString(final_string)); // deep copy + traceString = traceString + end_line + end_line + QString("#### saving camera placements for all active views") + + end_line + end_line + camera_qs + end_line; + } + } + } + return traceString; } /*! \brief Saves trace string to disk file */ -void PVGUI_Module::saveTrace(const char* theName) +void PVGUI_Module::saveTrace( const char* theName ) { - QFile file(theName); - if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { + QFile file( theName ); + if ( !file.open( QIODevice::WriteOnly | QIODevice::Text ) ) { MESSAGE( "Could not open file:" << theName ); return; } - QTextStream out(&file); + QTextStream out( &file ); out << getTraceString(); file.close(); } @@ -882,9 +867,9 @@ void PVGUI_Module::saveTrace(const char* theName) /*! \brief Saves ParaView state to a disk file */ -void PVGUI_Module::saveParaviewState(const char* theFileName) +void PVGUI_Module::saveParaviewState( const QString& theFileName ) { - pqApplicationCore::instance()->saveState(theFileName); + pqApplicationCore::instance()->saveState( theFileName.toStdString().c_str() ); } /*! @@ -892,20 +877,18 @@ void PVGUI_Module::saveParaviewState(const char* theFileName) */ void PVGUI_Module::clearParaviewState() { - QAction* deleteAllAction = action(DeleteAllId); - if (deleteAllAction) { - deleteAllAction->activate(QAction::Trigger); + QAction* deleteAllAction = action( DeleteAllId ); + if ( deleteAllAction ) { + deleteAllAction->activate( QAction::Trigger ); } } /*! \brief Restores ParaView state from a disk file - - If toClear == true, the current ojects will be deleted */ -void PVGUI_Module::loadParaviewState(const char* theFileName) +void PVGUI_Module::loadParaviewState( const QString& theFileName ) { - pqApplicationCore::instance()->loadState(theFileName, getActiveServer()); + pqApplicationCore::instance()->loadState( theFileName.toStdString().c_str(), getActiveServer() ); } /*! @@ -918,100 +901,56 @@ pqServer* PVGUI_Module::getActiveServer() /*! - \brief Creates PARAVIS preference pane + \brief Creates PARAVIS preferences panel. */ void PVGUI_Module::createPreferences() { - // Paraview settings tab - int aParaViewSettingsTab = addPreference( tr( "TIT_PVIEWSETTINGS" ) ); - int aPanel = addPreference(QString(), aParaViewSettingsTab, LightApp_Preferences::UserDefined, "PARAVIS", ""); - setPreferenceProperty(aPanel, "content", (qint64)(new PVGUI_ParaViewSettingsPane())); - - // Paravis settings tab - int aParaVisSettingsTab = addPreference( tr( "TIT_PVISSETTINGS" ) ); - addPreference( tr( "PREF_STOP_TRACE" ), aParaVisSettingsTab, LightApp_Preferences::Bool, "PARAVIS", "stop_trace"); - - int aSaveType = addPreference(tr( "PREF_SAVE_TYPE_LBL" ), aParaVisSettingsTab, - LightApp_Preferences::Selector, - "PARAVIS", "savestate_type"); QList aIndices; QStringList aStrings; - aIndices<<0<<1<<2; - aStrings<objectBrowser(); - bool isOBClient = (ob && theClient == ob->popupClientType()); - if (!isOBClient) { - return; - } + // Paraview settings tab + int aParaViewSettingsTab = addPreference( tr( "TIT_PVIEWSETTINGS" ) ); - // Get list of selected objects - LightApp_SelectionMgr* aSelectionMgr = getApp()->selectionMgr(); - SALOME_ListIO aListIO; - aSelectionMgr->selectedObjects(aListIO); - if (aListIO.Extent() == 1 && aListIO.First()->hasEntry()) { - QString entry = QString(aListIO.First()->getEntry()); - - // Get active study - SalomeApp_Study* activeStudy = - dynamic_cast(getApp()->activeStudy()); - if(!activeStudy) { - return; - } + setPreferenceProperty(aParaViewSettingsTab, "stretch", false ); + int aPanel = addPreference( QString(), aParaViewSettingsTab, + LightApp_Preferences::UserDefined, PARAVIS_MODULE_NAME, "" ); - // Get SALOMEDS client study - _PTR(Study) studyDS = activeStudy->studyDS(); - if(!studyDS) { - return; - } + setPreferenceProperty( aPanel, "content", (qint64)( new PVGUI_ParaViewSettingsPane( 0, getApp() ) ) ); - QString paravisDataType(GetEngine()->ComponentDataType()); - if(activeStudy && activeStudy->isComponent(entry) && - activeStudy->componentDataType(entry) == paravisDataType) { - // ParaViS module object - theMenu->addSeparator(); - theMenu->addAction(action(SaveStatePopupId)); - } - else { - // Try to get state object - _PTR(SObject) stateSObj = - studyDS->FindObjectID(entry.toLatin1().constData()); - if (!stateSObj) { - return; - } - - // Check local id - _PTR(GenericAttribute) anAttr; - if (!stateSObj->FindAttribute(anAttr, "AttributeLocalID")) { - return; - } + // Paravis settings tab + int aParaVisSettingsTab = addPreference( tr( "TIT_PVISSETTINGS" ) ); - _PTR(AttributeLocalID) anID(anAttr); - - if (anID->Value() == PVSTATEID) { - // Paraview state object - theMenu->addSeparator(); - theMenu->addAction(action(AddStatePopupId)); - theMenu->addAction(action(CleanAndAddStatePopupId)); - theMenu->addSeparator(); - theMenu->addAction(action(ParaVisRenameId)); - theMenu->addAction(action(ParaVisDeleteId)); - } - } - } + addPreference( tr( "PREF_NO_EXT_PVSERVER" ), aParaVisSettingsTab, + LightApp_Preferences::Bool, PARAVIS_MODULE_NAME, "no_ext_pv_server" ); + + int aSaveType = addPreference( tr( "PREF_SAVE_TYPE_LBL" ), aParaVisSettingsTab, + LightApp_Preferences::Selector, + PARAVIS_MODULE_NAME, "savestate_type" ); + + aStrings.clear(); + aIndices.clear(); + aIndices << 0 << 1 << 2; + aStrings << tr("PREF_SAVE_TYPE_0") << tr("PREF_SAVE_TYPE_1") << tr("PREF_SAVE_TYPE_2"); + setPreferenceProperty( aSaveType, "strings", aStrings ); + setPreferenceProperty( aSaveType, "indexes", aIndices ); + + // ... "Language" group <> + int traceGroup = addPreference( tr( "PREF_GROUP_TRACE" ), aParaVisSettingsTab ); + + int stopTrace = addPreference( tr( "PREF_STOP_TRACE" ), traceGroup, + LightApp_Preferences::Bool, PARAVIS_MODULE_NAME, "stop_trace" ); + setPreferenceProperty( stopTrace, "restart", true ); + + int aTraceType = addPreference( tr( "PREF_TRACE_TYPE_LBL" ), traceGroup, + LightApp_Preferences::Selector, + PARAVIS_MODULE_NAME, "tracestate_type" ); + aStrings.clear(); + aIndices.clear(); + aIndices << 0 << 1 << 2; + aStrings << tr("PREF_TRACE_TYPE_0") << tr("PREF_TRACE_TYPE_1") << tr("PREF_TRACE_TYPE_2"); + setPreferenceProperty( aTraceType, "strings", aStrings ); + setPreferenceProperty( aTraceType, "indexes", aIndices ); + setPreferenceProperty( aTraceType, "restart", true ); } /*! @@ -1039,270 +978,51 @@ void PVGUI_Module::onRestartTrace() } /*! - \brief Show ParaView view. + \brief. Close ParaView python trace. */ -void PVGUI_Module::onNewParaViewWindow() +void PVGUI_Module::onStopTrace() { - showView(true); + stopTrace(); } - /*! - \brief Save state under the module root object. + \brief Called when view manager is added */ -void PVGUI_Module::onSaveMultiState() +void PVGUI_Module::onViewManagerAdded( SUIT_ViewManager* vm ) { - // Create state study object - - // Get SALOMEDS client study - _PTR(Study) studyDS = PARAVIS::GetCStudy(this); - if(!studyDS) { - return; + if ( PVViewer_ViewManager* pvvm = dynamic_cast( vm ) ) { + connect( pvvm, SIGNAL( viewCreated( SUIT_ViewWindow* ) ), + this, SLOT( onPVViewCreated( SUIT_ViewWindow* ) ) ); + connect( pvvm, SIGNAL( deleteView( SUIT_ViewWindow* ) ), + this, SLOT( onPVViewDelete( SUIT_ViewWindow* ) ) ); } - - _PTR(SComponent) paravisComp = - studyDS->FindComponent(GetEngine()->ComponentDataType()); - if(!paravisComp) { - return; - } - - // Unlock the study if it is locked - bool isLocked = studyDS->GetProperties()->IsLocked(); - if (isLocked) { - studyDS->GetProperties()->SetLocked(false); - } - - QString stateName = tr("SAVED_PARAVIEW_STATE_NAME") + - QString::number(myStateCounter + 1); - - _PTR(StudyBuilder) studyBuilder = studyDS->NewBuilder(); - _PTR(SObject) newSObj = studyBuilder->NewObject(paravisComp); - - // Set name - _PTR(GenericAttribute) anAttr; - anAttr = studyBuilder->FindOrCreateAttribute(newSObj, "AttributeName"); - _PTR(AttributeName) nameAttr(anAttr); - - nameAttr->SetValue(stateName.toLatin1().constData()); - - // Set local id - anAttr = studyBuilder->FindOrCreateAttribute(newSObj, "AttributeLocalID"); - _PTR(AttributeLocalID) localIdAttr(anAttr); - - localIdAttr->SetValue(PVSTATEID); - - // Set file name - QString stateEntry = QString::fromStdString(newSObj->GetID()); - - // File name for state saving - QString tmpDir = QString::fromStdString(SALOMEDS_Tool::GetTmpDir()); - QString fileName = QString("%1_paravisstate:%2").arg(tmpDir, stateEntry); - - anAttr = studyBuilder->FindOrCreateAttribute(newSObj, "AttributeString"); - _PTR(AttributeString) stringAttr(anAttr); - - stringAttr->SetValue(fileName.toLatin1().constData()); - - // Lock the study back if necessary - if (isLocked) { - studyDS->GetProperties()->SetLocked(true); - } - - // Save state - saveParaviewState(fileName.toLatin1().constData()); - myTemporaryFiles.append(fileName); - - // Increment the counter - myStateCounter++; - - updateObjBrowser(); -} - -/*! - \brief Restore the selected state by merging with the current one. -*/ -void PVGUI_Module::onAddState() -{ - loadSelectedState(false); } /*! - \brief Clean the current state and restore the selected one. + \brief Called when view manager is removed */ -void PVGUI_Module::onCleanAddState() +void PVGUI_Module::onViewManagerRemoved( SUIT_ViewManager* vm ) { - loadSelectedState(true); + if ( PVViewer_ViewManager* pvvm = dynamic_cast( vm ) ) + disconnect( pvvm, SIGNAL( viewCreated( SUIT_ViewWindow* ) ), + this, SLOT( onPVViewCreated( SUIT_ViewWindow* ) ) ); } /*! - \brief Rename the selected object. + \brief Show toolbars at \a vw PV view window creating when PARAVIS is active. */ -void PVGUI_Module::onRename() -{ - LightApp_SelectionMgr* aSelectionMgr = getApp()->selectionMgr(); - SALOME_ListIO aListIO; - aSelectionMgr->selectedObjects(aListIO); - - if (aListIO.Extent() == 1 && aListIO.First()->hasEntry()) { - std::string entry = aListIO.First()->getEntry(); - - // Get SALOMEDS client study - _PTR(Study) studyDS = PARAVIS::GetCStudy(this); - if(!studyDS) { - return; - } - - // Unlock the study if it is locked - bool isLocked = studyDS->GetProperties()->IsLocked(); - if (isLocked) { - studyDS->GetProperties()->SetLocked(false); - } - - // Rename the selected state object - _PTR(SObject) stateSObj = studyDS->FindObjectID(entry); - if (!stateSObj) { - return; - } - - _PTR(GenericAttribute) anAttr; - if (stateSObj->FindAttribute(anAttr, "AttributeName")) { - _PTR(AttributeName) nameAttr (anAttr); - QString newName = - LightApp_NameDlg::getName(getApp()->desktop(), nameAttr->Value().c_str()); - if (!newName.isEmpty()) { - nameAttr->SetValue(newName.toLatin1().constData()); - aListIO.First()->setName(newName.toLatin1().constData()); - } - } - - // Lock the study back if necessary - if (isLocked) { - studyDS->GetProperties()->SetLocked(true); - } - - // Update object browser - updateObjBrowser(); - - } -} - -/*! - \brief Delete the selected objects. -*/ -void PVGUI_Module::onDelete() -{ - LightApp_SelectionMgr* aSelectionMgr = getApp()->selectionMgr(); - SALOME_ListIO aListIO; - aSelectionMgr->selectedObjects(aListIO); - - if (aListIO.Extent() == 1 && aListIO.First()->hasEntry()) { - std::string entry = aListIO.First()->getEntry(); - - // Get SALOMEDS client study - _PTR(Study) studyDS = PARAVIS::GetCStudy(this); - if(!studyDS) { - return; - } - - // Unlock the study if it is locked - bool isLocked = studyDS->GetProperties()->IsLocked(); - if (isLocked) { - studyDS->GetProperties()->SetLocked(false); - } - - // Remove the selected state from the study - _PTR(StudyBuilder) studyBuilder = studyDS->NewBuilder(); - _PTR(SObject) stateSObj = studyDS->FindObjectID(entry); - studyBuilder->RemoveObject(stateSObj); - - // Lock the study back if necessary - if (isLocked) { - studyDS->GetProperties()->SetLocked(true); - } - - // Update object browser - updateObjBrowser(); - } -} - -void PVGUI_Module::onPushTraceTimer() +void PVGUI_Module::onPVViewCreated( SUIT_ViewWindow* vw ) { -// MESSAGE("onPushTraceTimer(): Pushing trace to engine..."); - GetEngine()->PutPythonTraceStringToEngine(getTraceString().toStdString().c_str()); -} - -/*! - \brief Discover help project files from the resources. - \return name of the help file. -*/ -QString PVGUI_Module::getHelpFileName() { - QString aPVHome(getenv("PVHOME")); - if (aPVHome.isNull()) { - qWarning("Wariable PVHOME is not defined"); - return QString(); - } - QChar aSep = QDir::separator(); - //PARAVIEW_VERSION from the vtkPVConfig.h file - QString aFileName = aPVHome + aSep + "share" + aSep + "doc" + aSep + "paraview-"+ PARAVIEW_VERSION + aSep + "paraview.qch"; - return aFileName; + myGuiElements->setToolBarVisible( true ); + restoreDockWidgetsState(); } - /*! - \brief Load selected paraview state - - If toClear == true, the current state will be cleared + \brief Save toolbars state at \a view view closing. */ -void PVGUI_Module::loadSelectedState(bool toClear) +void PVGUI_Module::onPVViewDelete( SUIT_ViewWindow* view ) { - QString fileName; - - LightApp_SelectionMgr* aSelectionMgr = getApp()->selectionMgr(); - SALOME_ListIO aListIO; - aSelectionMgr->selectedObjects(aListIO); - - if (aListIO.Extent() == 1 && aListIO.First()->hasEntry()) { - std::string entry = aListIO.First()->getEntry(); - - // Get SALOMEDS client study - _PTR(Study) studyDS = PARAVIS::GetCStudy(this); - if(!studyDS) { - return; - } - - // Check local id - _PTR(SObject) stateSObj = studyDS->FindObjectID(entry); - _PTR(GenericAttribute) anAttr; - if (!stateSObj->FindAttribute(anAttr, "AttributeLocalID")) { - return; - } - _PTR(AttributeLocalID) anID(anAttr); - if (!anID->Value() == PVSTATEID) { - return; - } - - // Get state file name - if (stateSObj->FindAttribute(anAttr, "AttributeString")) { - _PTR(AttributeString) aStringAttr(anAttr); - QString stringValue(aStringAttr->Value().c_str()); - - if (QFile::exists(stringValue)) { - fileName = stringValue; - } - } - } - - if (!fileName.isEmpty()) { - if (toClear) { - clearParaviewState(); - } - - loadParaviewState(fileName.toLatin1().constData()); - } - else { - SUIT_MessageBox::critical(getApp()->desktop(), - tr("ERR_ERROR"), - tr("ERR_STATE_CANNOT_BE_RESTORED")); - } + if ( dynamic_cast( view ) ) + saveDockWidgetsState( false ); } /*!