X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FPVGUI%2FPVGUI_Module.cxx;h=02cc591668d560bb81929f488c044615f8ac326e;hb=46e35567d5421e5f833c3dcfaa56a4d7be35b0c0;hp=c8c1f421ad66d02e374157671735ec2c13f052a3;hpb=09c34352cd5ad238ba0f7c1296357d7889c4c47d;p=modules%2Fparavis.git diff --git a/src/PVGUI/PVGUI_Module.cxx b/src/PVGUI/PVGUI_Module.cxx index c8c1f421..02cc5916 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-2019 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 @@ -27,22 +27,16 @@ #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 "PVViewer_ViewManager.h" +#include "PVViewer_Core.h" #include "PVViewer_ViewWindow.h" #include "PVViewer_ViewModel.h" -#include "PVGUI_Tools.h" #include "PVGUI_ParaViewSettingsPane.h" #include "PVViewer_GUIElements.h" -#include "PVViewer_EngineWrapper.h" +#include "PVServer_ServiceWrapper.h" #include "PVGUI_DataModel.h" // SALOME Includes @@ -55,18 +49,11 @@ #include #include -#include -#include - #include #include #include -#include // should ultimately be a LightApp only -#include +#include #include -#include -#include -#include #include #include @@ -100,7 +87,6 @@ #include #include #include -#include #include #include #include @@ -109,10 +95,10 @@ #include #include #include +#include #include #include -#include #include #include #include @@ -122,7 +108,7 @@ #include #include #include -#include +//#include #include #include #include @@ -132,77 +118,39 @@ #include #include #include - -// TO REMOVE: -#include - -#include - +#include +#include +#include +#include +#include +#include +#include + +#if PY_VERSION_HEX < 0x03050000 +static char* +Py_EncodeLocale(const wchar_t *arg, size_t *size) +{ + return _Py_wchar2char(arg, size); +} +static wchar_t* +Py_DecodeLocale(const char *arg, size_t *size) +{ + return _Py_char2wchar(arg, size); +} +#endif //---------------------------------------------------------------------------- PVGUI_Module* ParavisModule = 0; -PVSERVER_ORB::PVSERVER_Gen_var PVGUI_Module::MyEngine; /*! \mainpage - TODO TODO update this: - -

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. - + 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. - 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) */ /*! @@ -211,48 +159,10 @@ PVSERVER_ORB::PVSERVER_Gen_var PVGUI_Module::MyEngine; SALOME module wrapping ParaView GUI. */ -_PTR(SComponent) -ClientFindOrCreateParavisComponent(_PTR(Study) theStudyDocument) -{ - _PTR(SComponent) aSComponent = theStudyDocument->FindComponent("PVSERVER"); - if (!aSComponent) { - _PTR(StudyBuilder) aStudyBuilder = theStudyDocument->NewBuilder(); - aStudyBuilder->NewCommand(); - int aLocked = theStudyDocument->GetProperties()->IsLocked(); - if (aLocked) theStudyDocument->GetProperties()->SetLocked(false); - aSComponent = aStudyBuilder->NewComponent("PVSERVER"); - _PTR(GenericAttribute) anAttr = - aStudyBuilder->FindOrCreateAttribute(aSComponent, "AttributeName"); - _PTR(AttributeName) aName (anAttr); - - ORB_INIT& init = *SINGLETON_::Instance(); - CORBA::ORB_var anORB = init( qApp->argc(), qApp->argv() ); - - SALOME_NamingService *NamingService = new SALOME_NamingService( anORB ); - CORBA::Object_var objVarN = NamingService->Resolve("/Kernel/ModulCatalog"); - SALOME_ModuleCatalog::ModuleCatalog_var Catalogue = - SALOME_ModuleCatalog::ModuleCatalog::_narrow(objVarN); - SALOME_ModuleCatalog::Acomponent_var Comp = Catalogue->GetComponent( "PVSERVER" ); - if (!Comp->_is_nil()) { - aName->SetValue(Comp->componentusername()); - } - - anAttr = aStudyBuilder->FindOrCreateAttribute(aSComponent, "AttributePixMap"); - _PTR(AttributePixMap) aPixmap (anAttr); - aPixmap->SetPixMap( "pqAppIcon16.png" ); - - // Create Attribute parameters for future using - anAttr = aStudyBuilder->FindOrCreateAttribute(aSComponent, "AttributeParameter"); - - aStudyBuilder->DefineComponentInstance(aSComponent, PVGUI_Module::GetCPPEngine()->GetIOR()); - if (aLocked) theStudyDocument->GetProperties()->SetLocked(true); - aStudyBuilder->CommitCommand(); - } - return aSComponent; -} - /*! - 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() @@ -267,38 +177,21 @@ void paravisCleanUp() \brief Constructor. Sets the default name for the module. */ PVGUI_Module::PVGUI_Module() - : SalomeApp_Module( PARAVIS_MODULE_NAME ), - mySelectionControlsTb( -1 ), + : LightApp_Module( PARAVIS_MODULE_NAME ), mySourcesMenuId( -1 ), myFiltersMenuId( -1 ), myMacrosMenuId(-1), - myToolbarsMenuId(-1), myRecentMenuId(-1), + myCatalystMenuId(-1), myOldMsgHandler(0), myTraceWindow(0), - myStateCounter(0), myInitTimer(0), - myPushTraceTimer(0), myGuiElements(0) { #ifdef HAS_PV_DOC Q_INIT_RESOURCE( PVGUI ); #endif ParavisModule = this; - - // Clear old copies of embedded macros files - QString aDestPath = QString( "%1/.config/%2/Macros" ).arg( QDir::homePath() ).arg( QApplication::applicationName() ); - QStringList aFilter; - aFilter << "*.py"; - - QDir aDestDir(aDestPath); - QStringList aDestFiles = aDestDir.entryList(aFilter, QDir::Files); - foreach (QString aMacrosPath, getEmbeddedMacrosList()) { - QString aMacrosName = QFileInfo(aMacrosPath).fileName(); - if (aDestFiles.contains(aMacrosName)) { - aDestDir.remove(aMacrosName); - } - } } /*! @@ -306,26 +199,19 @@ PVGUI_Module::PVGUI_Module() */ PVGUI_Module::~PVGUI_Module() { - if (myPushTraceTimer) - delete myPushTraceTimer; if (myInitTimer) delete myInitTimer; } -PVViewer_EngineWrapper * PVGUI_Module::GetEngine() -{ - return PVViewer_EngineWrapper::GetInstance(); -} - -PVSERVER_ORB::PVSERVER_Gen_var PVGUI_Module::GetCPPEngine() +/*! + \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() { - // initialize PARAVIS module engine (load, if necessary) - if ( CORBA::is_nil( MyEngine ) ) { - Engines::EngineComponent_var comp = - SalomeApp_Application::lcc()->FindOrLoad_Component( "FactoryServer", "PVSERVER" ); - MyEngine = PVSERVER_ORB::PVSERVER_Gen::_narrow( comp ); - } - return MyEngine; + return PVServer_ServiceWrapper::GetInstance(); } /*! @@ -337,9 +223,12 @@ CAM_DataModel* PVGUI_Module::createDataModel() return new PVGUI_DataModel( this ); } -pqPVApplicationCore * PVGUI_Module::GetPVApplication() +/*! + \brief Get the ParaView application singleton. +*/ +pqPVApplicationCore* PVGUI_Module::GetPVApplication() { - return PVViewer_ViewManager::GetPVApplication(); + return PVViewer_Core::GetPVApplication(); } /*! @@ -350,11 +239,6 @@ void PVGUI_Module::initialize( CAM_Application* app ) { LightApp_Module::initialize( app ); - // Create ParaViS actions - createActions(); - // Create ParaViS menus - createMenus(); - // Uncomment to debug ParaView initialization // "aa" used instead of "i" as GDB doesn't like "i" variables :) /* @@ -367,24 +251,42 @@ void PVGUI_Module::initialize( CAM_Application* app ) 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_ViewManager::ParaviewInitApp(aDesktop, anApp->logWindow()); + PVViewer_Core::ParaviewInitApp(aDesktop); + + // Clear old copies of embedded macros files + //QString aDestPath = QString( "%1/.config/%2/Macros" ).arg( QDir::homePath() ).arg( QApplication::applicationName() ); + QString aDestPath = pqCoreUtilities::getParaViewUserDirectory() + "/Macros"; + QStringList aFilter; + aFilter << "*.py"; + + QDir aDestDir(aDestPath); + QStringList aDestFiles = aDestDir.entryList(aFilter, QDir::Files); + foreach(QString aMacrosPath, getEmbeddedMacrosList()) { + QString aMacrosName = QFileInfo(aMacrosPath).fileName(); + if (aDestFiles.contains(aMacrosName)) { + aDestDir.remove(aMacrosName); + } + } + myGuiElements = PVViewer_GUIElements::GetInstance(aDesktop); - // Remember current state of desktop toolbars - QList foreignToolbars = aDesktop->findChildren(); + // [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(); - // Behaviors and connection must be instanciated *after* widgets are in place - // In PARAVIS module we do not wait for PVViewer_ViewWindow to be instanciated to have this: - PVViewer_ViewManager::ParaviewInitBehaviors(true, aDesktop); - PVViewer_ViewManager::ConnectToExternalPVServer(aDesktop); - pvCreateActions(); - pvCreateToolBars(); pvCreateMenus(); + pvCreateToolBars(); + + PVViewer_Core::ParaviewInitBehaviors(true, aDesktop); QList activeDocks = aDesktop->findChildren(); QList activeMenus = aDesktop->findChildren(); @@ -416,15 +318,31 @@ void PVGUI_Module::initialize( CAM_Application* app ) // } // } - PVViewer_ViewManager::ParaviewLoadConfigurations(); + // 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); @@ -444,12 +362,6 @@ void PVGUI_Module::initialize( CAM_Application* app ) 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(); @@ -467,27 +379,40 @@ 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 - trace start up + \brief Initialisation timer event - Starts up the Python trace */ void PVGUI_Module::onInitTimer() { @@ -515,6 +440,9 @@ QStringList PVGUI_Module::getEmbeddedMacrosList() return aFullPathSourceFiles; } +/*! + \brief Update the list of embedded macros +*/ void PVGUI_Module::updateMacros() { pqPythonManager* aPythonManager = pqPVApplicationCore::instance()->pythonManager(); @@ -535,7 +463,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 ); } @@ -545,11 +475,14 @@ void PVGUI_Module::windows( QMap& m ) const */ void PVGUI_Module::showView( bool toShow ) { + // 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 PVViewer_ViewManager( anApp->activeStudy(), anApp->desktop(), anApp->logWindow() ); + viewMgr = new PVViewer_ViewManager( anApp->activeStudy(), anApp->desktop() ); anApp->addViewManager( viewMgr ); connect( viewMgr, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ), anApp, SLOT( onCloseView( SUIT_ViewManager* ) ) ); @@ -561,7 +494,7 @@ void PVGUI_Module::showView( bool toShow ) // this also connects to the pvserver and instantiates relevant PV behaviors } - pvWnd->setShown( toShow ); + pvWnd->setVisible( toShow ); if ( toShow ) pvWnd->setFocus(); } @@ -573,7 +506,6 @@ void PVGUI_Module::showHelpForProxy( const QString& groupname, const QString& pr pqHelpReaction::showProxyHelp(groupname, proxyname); } - /*! \brief Slot to show the waiting state. */ @@ -600,25 +532,6 @@ void PVGUI_Module::endWaitCursor() QApplication::restoreOverrideCursor(); } -static void ParavisMessageOutput(QtMsgType type, const char *msg) -{ - switch(type) - { - case QtDebugMsg: - vtkOutputWindow::GetInstance()->DisplayText(msg); - break; - case QtWarningMsg: - vtkOutputWindow::GetInstance()->DisplayErrorText(msg); - break; - case QtCriticalMsg: - vtkOutputWindow::GetInstance()->DisplayErrorText(msg); - break; - case QtFatalMsg: - vtkOutputWindow::GetInstance()->DisplayErrorText(msg); - break; - } -} - /*! \brief Activate module. \param study current study @@ -627,8 +540,6 @@ static void ParavisMessageOutput(QtMsgType type, const char *msg) */ bool PVGUI_Module::activateModule( SUIT_Study* study ) { - myOldMsgHandler = qInstallMsgHandler(ParavisMessageOutput); - SUIT_ExceptionHandler::addCleanUpRoutine( paravisCleanUp ); storeCommonWindowsState(); @@ -640,15 +551,15 @@ bool PVGUI_Module::activateModule( SUIT_Study* study ) if ( mySourcesMenuId != -1 ) menuMgr()->show(mySourcesMenuId); if ( myFiltersMenuId != -1 ) menuMgr()->show(myFiltersMenuId); if ( myMacrosMenuId != -1 ) menuMgr()->show(myMacrosMenuId); - if ( myToolbarsMenuId != -1 ) menuMgr()->show(myToolbarsMenuId); + if ( myCatalystMenuId != -1 ) menuMgr()->show(myCatalystMenuId); // 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); +// 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 ); @@ -674,7 +585,11 @@ bool PVGUI_Module::activateModule( SUIT_Study* study ) if ( myRecentMenuId != -1 ) menuMgr()->show(myRecentMenuId); - ClientFindOrCreateParavisComponent(PARAVIS::GetCStudy(this)); + // VSR 18/10/2018 - 0023170: Workaround to re-select current index after module activation + QItemSelectionModel* selection_model = myGuiElements->getPipelineBrowserWidget()->getSelectionModel(); + QModelIndex idx = selection_model->currentIndex(); + selection_model->clearCurrentIndex(); + selection_model->setCurrentIndex(idx, QItemSelectionModel::ClearAndSelect); return isDone; } @@ -716,13 +631,12 @@ 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); + menuMgr()->hide(myCatalystMenuId); setMenuShown( false ); setToolShown( false ); @@ -731,7 +645,7 @@ bool PVGUI_Module::deactivateModule( SUIT_Study* study ) SUIT_ExceptionHandler::removeCleanUpRoutine( paravisCleanUp ); if (myOldMsgHandler) - qInstallMsgHandler(myOldMsgHandler); + qInstallMessageHandler(myOldMsgHandler); restoreCommonWindowsState(); @@ -749,29 +663,10 @@ bool PVGUI_Module::deactivateModule( SUIT_Study* study ) */ void PVGUI_Module::onApplicationClosed( SUIT_Application* theApp ) { - PVViewer_ViewManager::ParaviewCleanup(); - - int aAppsNb = SUIT_Session::session()->applications().size(); - if (aAppsNb == 1) { - deleteTemporaryFiles(); - } + 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. @@ -781,102 +676,88 @@ 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(); LightApp_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(PARAVIS_MODULE_NAME); - 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 = GetCPPEngine()->GetIOR(); - return QString(anIOR.in()); -} - /*! \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 ) { + // ??? + // Not sure this is the right fix, but the PYTHON_MANAGER has a function named + // executeScript() which seems to do what the runScript on pyShellDialog() class + // was doing. +#ifndef WNT + pqPythonManager* manager = + qobject_cast(pqApplicationCore::instance()->manager("PYTHON_MANAGER")); + + if ( manager ) { + manager->executeScript(script); + } +#endif + /* #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 + */ } ///** @@ -894,7 +775,7 @@ void PVGUI_Module::executeScript(const char *script) // PyObject * elem = PyList_GetItem(lst, i); // if (PyString_Check(elem)) // { -// std::cout << "At pos:" << i << ", " << PyString_AsString(elem) << std::endl; +// std::cout << "At pos:" << i << ", " << Py_EncodeLocale(PyUnicode_AS_UNICODE(elem), NULL) << std::endl; // } // else // std::cout << "At pos:" << i << ", not a string!" << std::endl; @@ -905,44 +786,68 @@ void PVGUI_Module::executeScript(const char *script) /*! \brief Returns trace string */ -static const QString MYReplaceStr("paraview.simple"); QString PVGUI_Module::getTraceString() { - vtkSMTrace *tracer = vtkSMTrace::GetActiveTracer(); - if (!tracer) // trace is not started - return QString(""); - - QString traceString(tracer->GetCurrentTrace()); - 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()); - // '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.isNull()) && traceString.length() != 0) { - int aPos = traceString.indexOf(MYReplaceStr); - while (aPos != -1) { - traceString = traceString.replace(aPos, MYReplaceStr.length(), "pvsimple"); - aPos = traceString.indexOf(MYReplaceStr, aPos); + 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 (trace_mod && trace_mod != Py_None && 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(PyUnicode_FromUnicode(Py_DecodeLocale(end_line.toStdString().c_str(), NULL), end_line.size())); + vtkSmartPyObject final_string(PyObject_CallMethod(ret, const_cast("join"), + const_cast("O"), (PyObject*)camera_trace)); + if (PyUnicode_CheckExact(final_string)) + { + QString camera_qs(Py_EncodeLocale(PyUnicode_AS_UNICODE(final_string.GetPointer()), NULL)); // 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(); } @@ -950,9 +855,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() ); } /*! @@ -960,20 +865,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() ); } /*! @@ -986,105 +889,56 @@ pqServer* PVGUI_Module::getActiveServer() /*! - \brief Creates PARAVIS preference pane + \brief Creates PARAVIS preferences panel. */ void PVGUI_Module::createPreferences() { + QList aIndices; + QStringList aStrings; + // Paraview settings tab int aParaViewSettingsTab = addPreference( tr( "TIT_PVIEWSETTINGS" ) ); setPreferenceProperty(aParaViewSettingsTab, "stretch", false ); - int aPanel = addPreference(QString(), aParaViewSettingsTab, LightApp_Preferences::UserDefined, PARAVIS_MODULE_NAME, ""); + int aPanel = addPreference( QString(), aParaViewSettingsTab, + LightApp_Preferences::UserDefined, PARAVIS_MODULE_NAME, "" ); - setPreferenceProperty(aPanel, "content", (qint64)(new PVGUI_ParaViewSettingsPane())); + setPreferenceProperty( aPanel, "content", (qint64)( new PVGUI_ParaViewSettingsPane( 0, getApp() ) ) ); // Paravis settings tab int aParaVisSettingsTab = addPreference( tr( "TIT_PVISSETTINGS" ) ); - addPreference( tr( "PREF_STOP_TRACE" ), aParaVisSettingsTab, LightApp_Preferences::Bool, PARAVIS_MODULE_NAME, "stop_trace"); - - 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"); - QList aIndices; - QStringList aStrings; - aIndices<<0<<1<<2; - aStrings<objectBrowser(); - bool isOBClient = (ob && theClient == ob->popupClientType()); - if (!isOBClient) { - return; - } - - // 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; - } - - // Get SALOMEDS client study - _PTR(Study) studyDS = activeStudy->studyDS(); - if(!studyDS) { - return; - } - - QString paravisDataType(PARAVIS_MODULE_NAME); - 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; - } - - _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 ); } /*! @@ -1112,262 +966,51 @@ void PVGUI_Module::onRestartTrace() } /*! - \brief Save state under the module root object. + \brief. Close ParaView python trace. */ -void PVGUI_Module::onSaveMultiState() +void PVGUI_Module::onStopTrace() { - // Create state study object - - // Get SALOMEDS client study - _PTR(Study) studyDS = PARAVIS::GetCStudy(this); - if(!studyDS) { - return; - } - - _PTR(SComponent) paravisComp = - studyDS->FindComponent(PARAVIS_MODULE_NAME); - 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. -*/ -void PVGUI_Module::onCleanAddState() -{ - loadSelectedState(true); + stopTrace(); } - /*! - \brief Rename the selected object. + \brief Called when view manager is added */ -void PVGUI_Module::onRename() +void PVGUI_Module::onViewManagerAdded( SUIT_ViewManager* vm ) { - 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(); - + 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* ) ) ); } } /*! - \brief Delete the selected objects. + \brief Called when view manager is removed */ -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::onViewManagerRemoved( SUIT_ViewManager* vm ) { - //MESSAGE("onPushTraceTimer(): Pushing trace to engine..."); - GetEngine()->PutPythonTraceStringToEngine(getTraceString().toStdString().c_str()); + if ( PVViewer_ViewManager* pvvm = dynamic_cast( vm ) ) + disconnect( pvvm, SIGNAL( viewCreated( SUIT_ViewWindow* ) ), + this, SLOT( onPVViewCreated( SUIT_ViewWindow* ) ) ); } /*! - \brief Discover help project files from the resources. - \return name of the help file. + \brief Show toolbars at \a vw PV view window creating when PARAVIS is active. */ -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; +void PVGUI_Module::onPVViewCreated( SUIT_ViewWindow* vw ) +{ + 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 ); } /*!