// PARAVIS : ParaView wrapper SALOME module
//
-// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+// 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
// License as published by the Free Software Foundation; either
-// version 2.1 of the License.
+// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
// File : PVGUI_Module.cxx
-// Author : Julia DOROVSKIKH
-//
+#define PARAVIS_MODULE_NAME "PARAVIS"
+
+#include <Standard_math.hxx> // 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 <vtkPython.h> // Python first
#include "PVGUI_Module.h"
-#include "PVGUI_Module_impl.h"
-#include "PVGUI_ProcessModuleHelper.h"
-#include "PVGUI_ViewModel.h"
-#include "PVGUI_ViewManager.h"
-#include "PVGUI_ViewWindow.h"
+#include CORBA_SERVER_HEADER(SALOME_ModuleCatalog)
+#include CORBA_SERVER_HEADER(SALOMEDS)
+
+#include "PVViewer_ViewManager.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 "PVGUI_DataModel.h"
+
+// SALOME Includes
+#include <utilities.h>
+#include <SUIT_DataBrowser.h>
#include <SUIT_Desktop.h>
#include <SUIT_MessageBox.h>
#include <SUIT_ResourceMgr.h>
#include <SUIT_Session.h>
-#include <LightApp_Application.h>
+#include <SUIT_OverrideCursor.h>
+#include <SUIT_ExceptionHandler.h>
+
+#include <SALOME_LifeCycleCORBA.hxx>
+#include <SALOMEDS_SObject.hxx>
+
#include <LightApp_SelectionMgr.h>
+#include <LightApp_NameDlg.h>
+#include <LightApp_Application.h>
+#include <SalomeApp_Application.h> // should ultimately be a LightApp only
+#include <SalomeApp_Study.h>
+#include <SALOME_ListIO.hxx>
+#include <SALOMEDS_Tool.hxx>
+#include <Utils_ORB_INIT.hxx>
+#include <Utils_SINGLETON.hxx>
+
#include <QtxActionMenuMgr.h>
#include <QtxActionToolMgr.h>
+#include <PARAVIS_version.h>
+
+// External includes
+#include <sstream>
+
#include <QAction>
#include <QApplication>
#include <QCursor>
#include <QFileInfo>
#include <QIcon>
#include <QInputDialog>
+#include <QMenu>
#include <QStatusBar>
#include <QString>
#include <QStringList>
#include <QTimer>
#include <QToolBar>
+#include <QTextStream>
+#include <QShortcut>
+#include <QDockWidget>
+#include <QHelpEngine>
+
+// Paraview includes
+#include <vtkPVConfig.h> // for symbol PARAVIEW_VERSION
+#include <vtkProcessModule.h>
+#include <vtkPVSession.h>
+#include <vtkPVProgressHandler.h>
+#include <vtkOutputWindow.h>
+#include <vtkEventQtSlotConnect.h>
+#include <vtkNew.h>
+#include <vtkSMProxy.h>
+#include <vtkSmartPointer.h>
+#include <vtkSMSession.h>
+#include <vtkSMTrace.h>
+#include <vtkSMSessionProxyManager.h>
+#include <vtkSMParaViewPipelineController.h>
#include <pqApplicationCore.h>
-#include <pqActiveServer.h>
-#include <pqActiveView.h>
-#include <pqClientAboutDialog.h>
+#include <pqPVApplicationCore.h>
#include <pqObjectBuilder.h>
#include <pqOptions.h>
-#include <pqRenderView.h>
-#include <pqRubberBandHelper.h>
+#include <pqSettings.h>
#include <pqServer.h>
-#include <pqServerManagerModel.h>
-#include <pqServerResource.h>
#include <pqUndoStack.h>
-#include <pqVCRController.h>
-#include <pqViewManager.h>
-#include <vtkPVMain.h>
-#include <vtkProcessModule.h>
+#include <pqTabbedMultiViewWidget.h>
+#include <pqActiveObjects.h>
+#include <pqHelpReaction.h>
+#include <pqPluginManager.h>
+#include <pqPythonDialog.h>
+#include <pqPythonManager.h>
+#include <pqLoadDataReaction.h>
+#include <pqPythonScriptEditor.h>
+#include <pqDataRepresentation.h>
+#include <pqDisplayColorWidget.h>
+#include <pqColorToolbar.h>
+#include <pqScalarBarVisibilityReaction.h>
+#include <pqServerResource.h>
+#include <pqServerConnectReaction.h>
+#include <pqPluginManager.h>
+#include <pqVCRToolbar.h>
+#include <pqAnimationScene.h>
+#include <pqServerManagerModel.h>
+#include <pqAnimationTimeToolbar.h>
-/*
- * Make sure all the kits register their classes with vtkInstantiator.
- * Since ParaView uses Tcl wrapping, all of VTK is already compiled in
- * anyway. The instantiators will add no more code for the linker to
- * collect.
- */
+//----------------------------------------------------------------------------
+PVGUI_Module* ParavisModule = 0;
+PVSERVER_ORB::PVSERVER_Gen_var PVGUI_Module::MyEngine;
-#include <vtkCommonInstantiator.h>
-#include <vtkFilteringInstantiator.h>
-#include <vtkGenericFilteringInstantiator.h>
-#include <vtkIOInstantiator.h>
-#include <vtkImagingInstantiator.h>
-#include <vtkInfovisInstantiator.h>
-#include <vtkGraphicsInstantiator.h>
+/*!
+ \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 <a href="../index.html">Sphinx documentation</a> first.
+
+ 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)
+*/
-#include <vtkRenderingInstantiator.h>
-#include <vtkVolumeRenderingInstantiator.h>
-#include <vtkHybridInstantiator.h>
-#include <vtkParallelInstantiator.h>
+/*!
+ \class PVGUI_Module
+ \brief Implementation
+ SALOME module wrapping ParaView GUI.
+*/
-#include <vtkPVServerCommonInstantiator.h>
-#include <vtkPVFiltersInstantiator.h>
-#include <vtkPVServerManagerInstantiator.h>
-#include <vtkClientServerInterpreter.h>
+_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_<ORB_INIT>::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" );
-//----------------------------------------------------------------------------
-// ClientServer wrapper initialization functions.
-// Taken from ParaView sources (file pqMain.cxx)
-extern "C" void vtkCommonCS_Initialize(vtkClientServerInterpreter*);
-extern "C" void vtkFilteringCS_Initialize(vtkClientServerInterpreter*);
-extern "C" void vtkGenericFilteringCS_Initialize(vtkClientServerInterpreter*);
-extern "C" void vtkImagingCS_Initialize(vtkClientServerInterpreter*);
-extern "C" void vtkInfovisCS_Initialize(vtkClientServerInterpreter*);
-extern "C" void vtkGraphicsCS_Initialize(vtkClientServerInterpreter*);
-extern "C" void vtkIOCS_Initialize(vtkClientServerInterpreter*);
-extern "C" void vtkRenderingCS_Initialize(vtkClientServerInterpreter*);
-extern "C" void vtkVolumeRenderingCS_Initialize(vtkClientServerInterpreter*);
-extern "C" void vtkHybridCS_Initialize(vtkClientServerInterpreter*);
-extern "C" void vtkWidgetsCS_Initialize(vtkClientServerInterpreter*);
-extern "C" void vtkParallelCS_Initialize(vtkClientServerInterpreter*);
-extern "C" void vtkPVServerCommonCS_Initialize(vtkClientServerInterpreter*);
-extern "C" void vtkPVFiltersCS_Initialize(vtkClientServerInterpreter*);
-extern "C" void vtkXdmfCS_Initialize(vtkClientServerInterpreter *);
+ // Create Attribute parameters for future using
+ anAttr = aStudyBuilder->FindOrCreateAttribute(aSComponent, "AttributeParameter");
-//----------------------------------------------------------------------------
-void ParaViewInitializeInterpreter(vtkProcessModule* pm)
-{
- // Initialize built-in wrapper modules.
- vtkCommonCS_Initialize(pm->GetInterpreter());
- vtkFilteringCS_Initialize(pm->GetInterpreter());
- vtkGenericFilteringCS_Initialize(pm->GetInterpreter());
- vtkImagingCS_Initialize(pm->GetInterpreter());
- vtkInfovisCS_Initialize(pm->GetInterpreter());
- vtkGraphicsCS_Initialize(pm->GetInterpreter());
- vtkIOCS_Initialize(pm->GetInterpreter());
- vtkRenderingCS_Initialize(pm->GetInterpreter());
- vtkVolumeRenderingCS_Initialize(pm->GetInterpreter());
- vtkHybridCS_Initialize(pm->GetInterpreter());
- vtkWidgetsCS_Initialize(pm->GetInterpreter());
- vtkParallelCS_Initialize(pm->GetInterpreter());
- vtkPVServerCommonCS_Initialize(pm->GetInterpreter());
- vtkPVFiltersCS_Initialize(pm->GetInterpreter());
- vtkXdmfCS_Initialize(pm->GetInterpreter());
-}
-
-vtkPVMain* PVGUI_Module::pqImplementation::myPVMain = 0;
-pqOptions* PVGUI_Module::pqImplementation::myPVOptions = 0;
-PVGUI_ProcessModuleHelper* PVGUI_Module::pqImplementation::myPVHelper = 0;
+ aStudyBuilder->DefineComponentInstance(aSComponent, PVGUI_Module::GetCPPEngine()->GetIOR());
+ if (aLocked) theStudyDocument->GetProperties()->SetLocked(true);
+ aStudyBuilder->CommitCommand();
+ }
+ return aSComponent;
+}
/*!
- \class PVGUI_Module
- \brief Implementation of light (no-CORBA-engine)
- SALOME module wrapping ParaView GUI.
+ \brief Clean up function
+
+ Used to stop ParaView progress events when
+ exception is caught by global exception handler.
*/
+void paravisCleanUp()
+{
+ if ( pqApplicationCore::instance() ) {
+ pqServer* s = pqApplicationCore::instance()->getActiveServer();
+ if ( s ) s->session()->GetProgressHandler()->CleanupPendingProgress();
+ }
+}
/*!
\brief Constructor. Sets the default name for the module.
*/
PVGUI_Module::PVGUI_Module()
- : LightApp_Module( "PARAVIS" ),
- Implementation( 0 ),
+ : SalomeApp_Module( PARAVIS_MODULE_NAME ),
mySelectionControlsTb( -1 ),
mySourcesMenuId( -1 ),
- myFiltersMenuId( -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 );
+#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);
+ }
+ }
}
/*!
*/
PVGUI_Module::~PVGUI_Module()
{
+ if (myPushTraceTimer)
+ delete myPushTraceTimer;
+ if (myInitTimer)
+ delete myInitTimer;
+}
+
+/*!
+ * \brief Retrieve the PVSERVER CORBA engine.
+ * This uses the Python wrapper provided
+ * by the PVViewer code in GUI (class PVViewer_EngineWrapper).
+ * \sa GetCPPEngine()
+ */
+PVViewer_EngineWrapper * PVGUI_Module::GetEngine()
+{
+ return PVViewer_EngineWrapper::GetInstance();
+}
+
+/*!
+ * \brief Retrieve the PVSERVER CORBA engine.
+ * Uses directly the standard Salome C++ mechanisms
+ * (LifeCycleCorba).
+ * \sa GetEngine()
+ */
+PVSERVER_ORB::PVSERVER_Gen_var PVGUI_Module::GetCPPEngine()
+{
+ // 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;
+}
+
+/*!
+ \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_ViewManager::GetPVApplication();
}
/*!
\brief Initialize module. Creates menus, prepares context menu, etc.
- \param app application instance
+ \param app SALOME GUI application instance
*/
void PVGUI_Module::initialize( CAM_Application* app )
{
LightApp_Module::initialize( app );
+ createActions();
+ createMenus();
+
// Uncomment to debug ParaView initialization
// "aa" used instead of "i" as GDB doesn't like "i" variables :)
/*
aa = aa;
}
*/
-
- pvInit();
+ LightApp_Application* anApp = getApp();
+ SUIT_Desktop* aDesktop = anApp->desktop();
+
+ // Remember current state of desktop toolbars
+ QList<QToolBar*> foreignToolbars = aDesktop->findChildren<QToolBar*>();
+
+ // Initialize ParaView client and associated behaviors
+ // and connect to externally launched pvserver
+ PVViewer_ViewManager::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();
+ pvCreateMenus();
+ pvCreateToolBars();
+
+ PVViewer_ViewManager::ParaviewInitBehaviors(true, aDesktop);
+
+ QList<QDockWidget*> activeDocks = aDesktop->findChildren<QDockWidget*>();
+ QList<QMenu*> activeMenus = aDesktop->findChildren<QMenu*>();
+
+ // Setup quick-launch shortcuts.
+ QShortcut *ctrlSpace = new QShortcut(Qt::CTRL + Qt::Key_Space, aDesktop);
+ QObject::connect(ctrlSpace, SIGNAL(activated()),
+ pqApplicationCore::instance(), SLOT(quickLaunch()));
+
+ // Find Plugin Dock Widgets
+ QList<QDockWidget*> currentDocks = aDesktop->findChildren<QDockWidget*>();
+ QList<QDockWidget*>::iterator i;
+ for (i = currentDocks.begin(); i != currentDocks.end(); ++i) {
+ if(!activeDocks.contains(*i)) {
+ myDockWidgets[*i] = false; // hidden by default
+ (*i)->hide();
+ }
+ }
+
+ // Find Plugin Menus
+ // [ABN] TODO: fix this - triggers a SEGFAULT at deactivation() time.
+// QList<QMenu*> currentMenus = aDesktop->findChildren<QMenu*>();
+// QList<QMenu*>::iterator im;
+// for (im = currentMenus.begin(); im != currentMenus.end(); ++im) {
+// if(!activeMenus.contains(*im)) {
+// QString s = (*im)->title();
+// std::cout << " MENU "<< s.toStdString() << std::endl;
+// myMenus.append(*im);
+// }
+// }
+
+ // Connect after toolbar creation, etc ... as some activations of the toolbars is triggered
+ // by the ServerConnection event:
+ PVViewer_ViewManager::ParaviewLoadConfigurations(true);
+ PVViewer_ViewManager::ConnectToExternalPVServer(aDesktop);
+ updateObjBrowser();
+
+ // Find created toolbars
+ QCoreApplication::processEvents();
+
+ // process PVViewer toolbars (might be added by PVViewer created BEFORE activating ParaVis)
+ QList<QToolBar*> 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<QToolBar*> allToolbars = aDesktop->findChildren<QToolBar*>();
+ foreach(QToolBar* aBar, allToolbars) {
+ if (!foreignToolbars.contains(aBar) && !myToolbars.contains(aBar)) {
+ myToolbars[aBar] = true;
+ myToolbarBreaks[aBar] = false;
+ aBar->setVisible(false);
+ aBar->toggleViewAction()->setVisible(false);
+ }
+ }
+
+ updateMacros();
+
+ SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr();
+ bool isStop = aResourceMgr->booleanValue( PARAVIS_MODULE_NAME, "stop_trace", false );
+ if(!isStop)
+ {
+ // Start a timer to schedule asap:
+ // - 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();
+
+ vtkProcessModule* pm = vtkProcessModule::GetProcessModule();
+ if(pm) {
+ vtkPVSession* pvs = dynamic_cast<vtkPVSession*>(pm->GetSession());
+ if(pvs) {
+ vtkPVProgressHandler* ph = pvs->GetProgressHandler();
+ if(ph) {
+ this->VTKConnect->Connect(ph, vtkCommand::StartEvent,
+ this, SLOT(onStartProgress()));
+ this->VTKConnect->Connect(ph, vtkCommand::EndEvent,
+ this, SLOT(onEndProgress()));
+ }
+ }
+ }
}
/*!
- \brief Get list of compliant dockable GUI elements
- \param m map to be filled in ("type":"default_position")
-*/
-void PVGUI_Module::windows( QMap<int, int>& m ) const
+ * \brief Slot called when the progress bar starts.
+ */
+void PVGUI_Module::onStartProgress()
{
- m.insert( LightApp_Application::WT_ObjectBrowser, Qt::LeftDockWidgetArea );
- m.insert( LightApp_Application::WT_PyConsole, Qt::BottomDockWidgetArea );
- // ParaView diagnostic output redirected here
- m.insert( LightApp_Application::WT_LogWindow, Qt::BottomDockWidgetArea );
+ // 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 Create custom popup menu selection object.
- \return new selected object
-*/
-/*LightApp_Selection* PVGUI_Module::createSelection() const
+ * \brief Slot called when the progress bar is done.
+ */
+void PVGUI_Module::onEndProgress()
{
- return new PVGUI_Selection();
-}*/
+ // 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<SalomeApp_Study*>(application()->activeStudy());
+ if(!activeStudy) return;
+
+ activeStudy->Modified();
+}
/*!
- \brief Create data model.
- \return module specific data model
+ \brief Initialisation timer event - Starts up the Python trace
*/
-/*CAM_DataModel* PVGUI_Module::createDataModel()
+void PVGUI_Module::onInitTimer()
{
- return new PVGUI_DataModel( this );
-}*/
-
+ startTrace();
+}
+
/*!
- \brief Static method, performs initialization of ParaView session.
- \return \c true if ParaView has been initialized successfully, otherwise false
+ \brief Get list of embedded macros files
*/
-bool PVGUI_Module::pvInit()
+QStringList PVGUI_Module::getEmbeddedMacrosList()
{
- if ( !pqImplementation::myPVMain ){
- // Obtain command-line arguments
- int argc = 0;
- QStringList args = QApplication::arguments();
- char** argv = new char*[args.size()];
- for ( QStringList::const_iterator it = args.begin(); argc < 1 && it != args.end(); it++, argc++ )
- argv[argc] = strdup( (*it).toLatin1().constData() );
+ QString aRootDir = getenv("PARAVIS_ROOT_DIR");
- vtkPVMain::SetInitializeMPI(0); // pvClient never runs with MPI.
- vtkPVMain::Initialize(&argc, &argv); // Perform any initializations.
+ QString aSourcePath = aRootDir + "/bin/salome/Macro";
- // TODO: Set plugin dir from preferences
- //QApplication::setLibraryPaths(QStringList(dir.absolutePath()));
+ QStringList aFilter;
+ aFilter << "*.py";
- pqImplementation::myPVMain = vtkPVMain::New();
- if ( !pqImplementation::myPVOptions )
- pqImplementation::myPVOptions = pqOptions::New();
- if ( !pqImplementation::myPVHelper )
- pqImplementation::myPVHelper = PVGUI_ProcessModuleHelper::New();
-
- pqImplementation::myPVOptions->SetProcessType(vtkPVOptions::PVCLIENT);
-
- // This creates the Process Module and initializes it.
- int ret = pqImplementation::myPVMain->Initialize(pqImplementation::myPVOptions,
- pqImplementation::myPVHelper,
- ParaViewInitializeInterpreter,
- argc, argv);
- if (!ret){
- // Tell process module that we support Multiple connections.
- // This must be set before starting the event loop.
- vtkProcessModule::GetProcessModule()->SupportMultipleConnectionsOn();
- ret = pqImplementation::myPVHelper->Run(pqImplementation::myPVOptions);
- }
+ QDir aSourceDir(aSourcePath);
+ QStringList aSourceFiles = aSourceDir.entryList(aFilter, QDir::Files);
+ QStringList aFullPathSourceFiles;
+ foreach (QString aMacrosName, aSourceFiles) {
+ aFullPathSourceFiles << aSourceDir.absoluteFilePath(aMacrosName);
+ }
+ return aFullPathSourceFiles;
+}
- delete[] argv;
- return !ret;
+/*!
+ \brief Update the list of embedded macros
+*/
+void PVGUI_Module::updateMacros()
+{
+ pqPythonManager* aPythonManager = pqPVApplicationCore::instance()->pythonManager();
+ if(!aPythonManager) {
+ return;
}
- return true;
+ foreach (QString aStr, getEmbeddedMacrosList()) {
+ aPythonManager->addMacro(aStr);
+ }
}
-
+
+
/*!
- \brief Static method, cleans up ParaView session at application exit.
+ \brief Get list of compliant dockable GUI elements
+ \param m map to be filled in ("type":"default_position")
*/
-void PVGUI_Module::pvShutdown()
+void PVGUI_Module::windows( QMap<int, int>& m ) const
{
- // TODO...
-}
+ m.insert( LightApp_Application::WT_ObjectBrowser, Qt::LeftDockWidgetArea );
+ m.insert( LightApp_Application::WT_PyConsole, Qt::BottomDockWidgetArea );
+ // ParaView diagnostic output redirected here
+ m.insert( LightApp_Application::WT_LogWindow, Qt::BottomDockWidgetArea );
+}
/*!
\brief Shows (toShow = true) or hides ParaView view window
*/
void PVGUI_Module::showView( bool toShow )
{
- // TODO: check if ParaView view already exists
- if ( !Implementation ){
- LightApp_Application* anApp = getApp();
- SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
- PVGUI_ViewManager* viewMgr = new PVGUI_ViewManager( anApp->activeStudy(), anApp->desktop() );
+ LightApp_Application* anApp = getApp();
+ PVViewer_ViewManager* viewMgr =
+ dynamic_cast<PVViewer_ViewManager*>( anApp->getViewManager( PVViewer_Viewer::Type(), false ) );
+ if ( !viewMgr ) {
+ viewMgr = new PVViewer_ViewManager( anApp->activeStudy(), anApp->desktop(), anApp->logWindow() );
anApp->addViewManager( viewMgr );
connect( viewMgr, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
anApp, SLOT( onCloseView( SUIT_ViewManager* ) ) );
- //connect( viewMgr, SIGNAL( viewCreated( SUIT_ViewWindow* ) ), vm, SLOT( onViewCreated( SUIT_ViewWindow* ) ) );
- //connect( viewMgr, SIGNAL( deleteView( SUIT_ViewWindow* ) ), this, SLOT( onViewDeleted( SUIT_ViewWindow* ) ) );
- SUIT_ViewWindow* wnd = viewMgr->createViewWindow();
-
- // Simulate ParaView client main window
- Implementation = new pqImplementation( anApp->desktop() );
- PVGUI_ViewWindow* pvWnd = dynamic_cast<PVGUI_ViewWindow*>( wnd );
- pvWnd->setMultiViewManager( &Implementation->Core.multiViewManager() );
-
- setupDockWidgets();
-
- pvCreateActions();
- pvCreateMenus();
- pvCreateToolBars();
-
- setupDockWidgetsContextMenu();
+ }
- // Now that we're ready, initialize everything ...
- Implementation->Core.initializeStates();
+ PVViewer_ViewWindow* pvWnd = dynamic_cast<PVViewer_ViewWindow*>( viewMgr->getActiveView() );
+ if ( !pvWnd ) {
+ pvWnd = dynamic_cast<PVViewer_ViewWindow*>( viewMgr->createViewWindow() );
+ // this also connects to the pvserver and instantiates relevant PV behaviors
}
- else
- restoreDockWidgetsState();
+
+ pvWnd->setShown( toShow );
+ if ( toShow ) pvWnd->setFocus();
}
/*!
- \brief Manage the label of Undo operation.
+ \brief Slot to show help for proxy.
*/
-void PVGUI_Module::onUndoLabel( const QString& label )
+void PVGUI_Module::showHelpForProxy( const QString& groupname, const QString& proxyname )
{
- action(UndoId)->setText(
- label.isEmpty() ? tr("MEN_CANTUNDO") : QString(tr("MEN_UNDO_ACTION")).arg(label));
- action(UndoId)->setStatusTip(
- label.isEmpty() ? tr("MEN_CANTUNDO") : QString(tr("MEN_UNDO_ACTION_TIP")).arg(label));
+ pqHelpReaction::showProxyHelp(groupname, proxyname);
}
+
/*!
- \brief Manage the label of Redo operation.
+ \brief Slot to show the waiting state.
*/
-void PVGUI_Module::onRedoLabel( const QString& label )
+void PVGUI_Module::onPreAccept()
{
- action(RedoId)->setText(
- label.isEmpty() ? tr("MEN_CANTREDO") : QString(tr("MEN_REDO_ACTION")).arg(label));
- action(RedoId)->setStatusTip(
- label.isEmpty() ? tr("MEN_CANTREDO") : QString(tr("MEN_REDO_ACTION_TIP")).arg(label));
+ getApp()->desktop()->statusBar()->showMessage(tr("STB_PREACCEPT"));
+ QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
}
/*!
- \brief Manage the label of Undo Camera operation.
+ \brief Slot to show the ready state.
*/
-void PVGUI_Module::onCameraUndoLabel( const QString& label )
+void PVGUI_Module::onPostAccept()
{
- action(CameraUndoId)->setText(
- label.isEmpty() ? tr("MEN_CANT_CAMERA_UNDO") : QString(tr("MEN_CAMERA_UNDO_ACTION")).arg(label));
- action(CameraUndoId)->setStatusTip(
- label.isEmpty() ? tr("MEN_CANT_CAMERA_UNDO") : QString(tr("MEN_CAMERA_UNDO_ACTION_TIP")).arg(label));
+ getApp()->desktop()->statusBar()->showMessage(tr("STB_POSTACCEPT"), 2000);
+ QTimer::singleShot(0, this, SLOT(endWaitCursor()));
}
/*!
- \brief Manage the label of Redo Camera operation.
+ \brief Slot to switch off wait cursor.
*/
-void PVGUI_Module::onCameraRedoLabel( const QString& label )
+void PVGUI_Module::endWaitCursor()
{
- action(CameraRedoId)->setText(
- label.isEmpty() ? tr("MEN_CANT_CAMERA_REDO") : QString(tr("MEN_CAMERA_REDO_ACTION")).arg(label));
- action(CameraRedoId)->setStatusTip(
- label.isEmpty() ? tr("MEN_CANT_CAMERA_REDO") : QString(tr("MEN_CAMERA_REDO_ACTION_TIP")).arg(label));
+ QApplication::restoreOverrideCursor();
}
/*!
- \brief Slot to delete all objects.
+ \brief Handler method for the output of messages.
*/
-void PVGUI_Module::onDeleteAll()
+static void ParavisMessageOutput(QtMsgType type, const char *msg)
{
- pqObjectBuilder* builder = pqApplicationCore::instance()->getObjectBuilder();
- Implementation->Core.getApplicationUndoStack()->beginUndoSet("Delete All");
- builder->destroyPipelineProxies();
- Implementation->Core.getApplicationUndoStack()->endUndoSet();
+ 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 Slot to check/uncheck the action for corresponding selection mode.
+ \brief Activate module.
+ \param study current study
+ \return \c true if activaion is done successfully or 0 to prevent
+ activation on error
*/
-void PVGUI_Module::onSelectionModeChanged( int mode )
+bool PVGUI_Module::activateModule( SUIT_Study* study )
{
- if( toolMgr()->toolBar( mySelectionControlsTb )->isEnabled() ) {
- if(mode == pqRubberBandHelper::SELECT) //surface selection
- action(SelectCellsOnId)->setChecked(true);
- else if(mode == pqRubberBandHelper::SELECT_POINTS) //surface selection
- action(SelectPointsOnId)->setChecked(true);
- else if(mode == pqRubberBandHelper::FRUSTUM)
- action(SelectCellsThroughId)->setChecked(true);
- else if(mode == pqRubberBandHelper::FRUSTUM_POINTS)
- action(SelectPointsThroughId)->setChecked(true);
- else if (mode == pqRubberBandHelper::BLOCKS)
- action(SelectBlockId)->setChecked(true);
- else // INTERACT
- action(InteractId)->setChecked(true);
+ myOldMsgHandler = qInstallMsgHandler(ParavisMessageOutput);
+
+ SUIT_ExceptionHandler::addCleanUpRoutine( paravisCleanUp );
+
+ storeCommonWindowsState();
+
+ 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 ( myMacrosMenuId != -1 ) menuMgr()->show(myMacrosMenuId);
+ if ( myToolbarsMenuId != -1 ) menuMgr()->show(myToolbarsMenuId);
+
+ // 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 );
+
+ restoreDockWidgetsState();
+
+ QMenu* aMenu = menuMgr()->findMenu( myRecentMenuId );
+ if(aMenu) {
+ QList<QAction*> anActns = aMenu->actions();
+ for (int i = 0; i < anActns.size(); ++i) {
+ QAction* a = anActns.at(i);
+ if(a)
+ a->setVisible(true);
+ }
}
+
+ QList<QMenu*>::iterator it;
+ for (it = myMenus.begin(); it != myMenus.end(); ++it) {
+ QAction* a = (*it)->menuAction();
+ if(a)
+ a->setVisible(true);
+ }
+
+ if ( myRecentMenuId != -1 ) menuMgr()->show(myRecentMenuId);
+
+ ClientFindOrCreateParavisComponent(PARAVIS::GetCStudy(this));
+
+ return isDone;
}
+
/*!
- \brief Slot to manage the change of axis center.
+ \brief Deactivate module.
+ \param study current study
+ \return \c true if deactivaion is done successfully or 0 to prevent
+ deactivation on error
*/
-void PVGUI_Module::onShowCenterAxisChanged( bool enabled )
+bool PVGUI_Module::deactivateModule( SUIT_Study* study )
{
- action(ShowCenterId)->setEnabled(enabled);
- action(ShowCenterId)->blockSignals(true);
- pqRenderView* renView = qobject_cast<pqRenderView*>(
- pqActiveView::instance().current());
- action(ShowCenterId)->setChecked( renView ? renView->getCenterAxesVisibility() : false);
- action(ShowCenterId)->blockSignals(false);
+ MESSAGE("PARAVIS deactivation ...")
+
+ QMenu* aMenu = menuMgr()->findMenu( myRecentMenuId );
+ if(aMenu) {
+ QList<QAction*> anActns = aMenu->actions();
+ for (int i = 0; i < anActns.size(); ++i) {
+ QAction* a = anActns.at(i);
+ if(a)
+ a->setVisible(false);
+ }
+ }
+
+ QList<QMenu*>::iterator it;
+ for (it = myMenus.begin(); it != myMenus.end(); ++it) {
+ QAction* a = (*it)->menuAction();
+ if(a)
+ a->setVisible(false);
+ }
+
+ QList<QDockWidget*> aStreamingViews = application()->desktop()->findChildren<QDockWidget*>("pqStreamingControls");
+ foreach(QDockWidget* aView, aStreamingViews) {
+ if (!myDockWidgets.contains(aView))
+ myDockWidgets[aView] = aView->isVisible();
+ }
+
+ /*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 );
+
+ saveDockWidgetsState();
+
+ SUIT_ExceptionHandler::removeCleanUpRoutine( paravisCleanUp );
+
+ if (myOldMsgHandler)
+ qInstallMsgHandler(myOldMsgHandler);
+
+ restoreCommonWindowsState();
+
+ return LightApp_Module::deactivateModule( study );
}
+
/*!
- \brief Slot to set tooltips for the first anf the last frames, i.e. a time range of animation.
+ \brief Called when application is closed.
+
+ Process finalize application functionality from ParaView in order to save server settings
+ and nullify application pointer if the application is being closed.
+
+ \param theApp application
*/
-void PVGUI_Module::setTimeRanges( double start, double end )
+void PVGUI_Module::onApplicationClosed( SUIT_Application* theApp )
{
- action(FirstFrameId)->setToolTip(QString("First Frame (%1)").arg(start, 0, 'g'));
- action(LastFrameId)->setToolTip(QString("Last Frame (%1)").arg(end, 0, 'g'));
+ PVViewer_ViewManager::ParaviewCleanup();
+
+ int aAppsNb = SUIT_Session::session()->applications().size();
+ if (aAppsNb == 1) {
+ deleteTemporaryFiles();
+ }
+ CAM_Module::onApplicationClosed(theApp);
}
+
/*!
- \brief Slot to manage the plaing process of animation.
+ \brief Deletes temporary files created during import operation from VISU
*/
-void PVGUI_Module::onPlaying( bool playing )
+void PVGUI_Module::deleteTemporaryFiles()
{
- SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
- if(playing) {
- disconnect( action(PlayId), SIGNAL( triggered() ),
- &Implementation->Core.VCRController(), SLOT( onPlay() ) );
- connect( action(PlayId), SIGNAL( triggered() ),
- &Implementation->Core.VCRController(), SLOT( onPause() ) );
- action(PlayId)->setIcon(QIcon(resMgr->loadPixmap("ParaView",tr("ICON_PAUSE"),false)));
- action(PlayId)->setText("Pa&use");
- }
- else {
- connect( action(PlayId), SIGNAL( triggered() ),
- &Implementation->Core.VCRController(), SLOT( onPlay() ) );
- disconnect( action(PlayId), SIGNAL( triggered() ),
- &Implementation->Core.VCRController(), SLOT( onPause() ) );
- action(PlayId)->setIcon(QIcon(resMgr->loadPixmap("ParaView",tr("ICON_PLAY"),false)));
- action(PlayId)->setText("&Play");
+ foreach(QString aFile, myTemporaryFiles) {
+ if (QFile::exists(aFile)) {
+ QFile::remove(aFile);
+ }
}
+}
+
+
+/*!
+ \brief Called when study is closed.
+
+ Removes data model from the \a study.
+
+ \param study study being closed
+*/
+void PVGUI_Module::studyClosed(SUIT_Study* study)
+{
+ clearParaviewState();
- Implementation->Core.setSelectiveEnabledState(!playing);
+ LightApp_Module::studyClosed(study);
}
/*!
- \brief Slot to add camera link.
+ \brief Called when study is opened.
*/
-void PVGUI_Module::onAddCameraLink()
+void PVGUI_Module::onModelOpened()
{
- pqView* vm = pqActiveView::instance().current();
- pqRenderView* rm = qobject_cast<pqRenderView*>(vm);
- if(rm) rm->linkToOtherView();
- else SUIT_MessageBox::warning(getApp()->desktop(),
- tr("WARNING"), tr("WRN_ADD_CAMERA_LINK"));
+ _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 Slot to show information about ParaView.
+\brief Returns IOR of current engine
*/
-void PVGUI_Module::onHelpAbout()
+QString PVGUI_Module::engineIOR() const
{
- pqClientAboutDialog* const dialog = new pqClientAboutDialog(getApp()->desktop());
- dialog->setAttribute(Qt::WA_DeleteOnClose);
- dialog->show();
+ CORBA::String_var anIOR = GetCPPEngine()->GetIOR();
+ return QString(anIOR.in());
}
/*!
- \brief Slot to show help for proxy.
+ \brief Open file of format supported by ParaView
*/
-void PVGUI_Module::showHelpForProxy( const QString& proxy )
+void PVGUI_Module::openFile(const char* theName)
{
- // make sure assistant is ready
- this->makeAssistant();
+ QStringList aFiles;
+ aFiles<<theName;
+ pqLoadDataReaction::loadData(aFiles);
+}
- if(this->Implementation->AssistantClient) {
- this->Implementation->AssistantClient->openAssistant();
- QString page("%1/Documentation/%2.html");
- page = page.arg(this->Implementation->DocumentationDir);
- page = page.arg(proxy);
- this->Implementation->AssistantClient->showPage(page);
- }
+/**!
+ * \brief Starts Python trace.
+ *
+ * Start trace invoking the newly introduced C++ API (PV 4.2)
+ * (inspired from pqTraceReaction::start())
+ */
+void PVGUI_Module::startTrace()
+{
+ vtkSMSessionProxyManager* pxm = pqActiveObjects::instance().activeServer()->proxyManager();
+
+ vtkSmartPointer<vtkSMProxy> proxy;
+ proxy.TakeReference(pxm->NewProxy("pythontracing", "PythonTraceOptions"));
+ if (proxy)
+ {
+ vtkNew<vtkSMParaViewPipelineController> 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);
+ }
+}
+
+/**!
+ * \brief Stops Python trace.
+ */
+void PVGUI_Module::stopTrace()
+{
+ vtkSMTrace::StopTrace();
+}
+
+/**!
+ * \brief Execute a Python script.
+ */
+void PVGUI_Module::executeScript(const char *script)
+{
+#ifndef WNT
+ pqPythonManager* manager = qobject_cast<pqPythonManager*>(
+ pqApplicationCore::instance()->manager("PYTHON_MANAGER"));
+ if (manager) {
+ pqPythonDialog* pyDiag = manager->pythonShellDialog();
+ if (pyDiag) {
+ pyDiag->runString(script);
+ }
+ }
+#endif
}
-QString Locate( const QString& appName )
+///**
+// * Debug function printing out the given interpreter's execution context
+// */
+//void printInterpContext(PyInterp_Interp * interp )
+//{
+// // Extract __smtraceString from interpreter's context
+// const PyObject* ctxt = interp->getExecutionContext();
+//
+// PyObject* lst = PyDict_Keys((PyObject *)ctxt);
+// Py_ssize_t siz = PyList_GET_SIZE(lst);
+// for (Py_ssize_t i = 0; i < siz; i++)
+// {
+// PyObject * elem = PyList_GetItem(lst, i);
+// if (PyString_Check(elem))
+// {
+// std::cout << "At pos:" << i << ", " << PyString_AsString(elem) << std::endl;
+// }
+// else
+// std::cout << "At pos:" << i << ", not a string!" << std::endl;
+// }
+// Py_XDECREF(lst);
+//}
+
+/*!
+ \brief Returns trace string
+*/
+static const QString MYReplaceStr("paraview.simple");
+QString PVGUI_Module::getTraceString()
{
- QString app_dir = QCoreApplication::applicationDirPath();
- const char* inst_dirs[] = {
- "/./",
- "/../bin/",
- "/../../bin/",
- 0
- };
- for (const char** dir = inst_dirs; *dir; ++dir) {
- QString path = app_dir;
- path += *dir;
- path += appName;
- //cout << "Checking : " << path.toAscii().data() << " ... ";
- //cout.flush();
- QFileInfo finfo (path);
- if (finfo.exists()) {
- //cout << " Success!" << endl;
- return path;
+ 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);
}
- //cout << " Failed" << endl;
}
- return app_dir + QDir::separator() + appName;
+
+ return traceString;
}
/*!
- \brief Initialized an assistant client.
+ \brief Saves trace string to disk file
*/
-void PVGUI_Module::makeAssistant()
+void PVGUI_Module::saveTrace(const char* theName)
{
- if(this->Implementation->AssistantClient)
+ QFile file(theName);
+ if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
+ MESSAGE( "Could not open file:" << theName );
return;
-
- QString assistantExe;
- QString profileFile;
-
- const char* assistantName = "assistant";
-#ifdef WNT
- const char* binDir = "\\";
- const char* binDir1 = "\\..\\";
-#else
- const char* binDir = "/bin/";
- const char* binDir1 = "/bin/bin/";
-#endif
-
- QString helper = QString(getenv("PVHOME")) + binDir + QString("pqClientDocFinder.txt");
- if(!QFile::exists(helper))
- helper = QString(getenv("PVHOME")) + binDir1 + QString("pqClientDocFinder.txt");
- if(QFile::exists(helper)) {
- QFile file(helper);
- if(file.open(QIODevice::ReadOnly)) {
- assistantExe = file.readLine().trimmed();
- profileFile = file.readLine().trimmed();
- // CMake escapes spaces, we need to unescape those.
- assistantExe.replace("\\ ", " ");
- profileFile.replace("\\ ", " ");
- }
- }
-
- if(assistantExe.isEmpty()) {
- assistantExe = ::Locate(assistantName);//assistantExe = ::Locate(assistantProgName);
- /*
- QString assistant = QCoreApplication::applicationDirPath();
- assistant += QDir::separator();
- assistant += assistantName;
- assistantExe = assistant;
- */
- }
-
- this->Implementation->AssistantClient = new QAssistantClient(assistantExe, this);
- QObject::connect(this->Implementation->AssistantClient, SIGNAL(error(const QString&)),
- this, SLOT(assistantError(const QString&)));
-
- QStringList args;
- args.append(QString("-profile"));
-
- if(profileFile.isEmpty()) {
- // see if help is bundled up with the application
- QString profile = ::Locate("pqClient.adp");
- /*QCoreApplication::applicationDirPath() + QDir::separator()
- + QString("pqClient.adp");*/
-
- if(QFile::exists(profile))
- profileFile = profile;
}
+ QTextStream out(&file);
+ out << getTraceString();
+ file.close();
+}
- if(profileFile.isEmpty() && getenv("PARAVIEW_HELP")) {
- // not bundled, ask for help
- args.append(getenv("PARAVIEW_HELP"));
+/*!
+ \brief Saves ParaView state to a disk file
+*/
+void PVGUI_Module::saveParaviewState(const char* theFileName)
+{
+ pqApplicationCore::instance()->saveState(theFileName);
+}
+
+/*!
+ \brief Delete all objects for Paraview Pipeline Browser
+*/
+void PVGUI_Module::clearParaviewState()
+{
+ QAction* deleteAllAction = action(DeleteAllId);
+ if (deleteAllAction) {
+ deleteAllAction->activate(QAction::Trigger);
}
- else if(profileFile.isEmpty()) {
- // no help, error out
- SUIT_MessageBox::critical(getApp()->desktop(),"Help error", "Couldn't find"
- " pqClient.adp.\nTry setting the PARAVIEW_HELP environment variable which"
- " points to that file");
- delete this->Implementation->AssistantClient;
+}
+
+/*!
+ \brief Restores ParaView state from a disk file
+
+ If toClear == true, the current ojects will be deleted
+*/
+void PVGUI_Module::loadParaviewState(const char* theFileName)
+{
+ pqApplicationCore::instance()->loadState(theFileName, getActiveServer());
+}
+
+/*!
+ \brief Returns current active ParaView server
+*/
+pqServer* PVGUI_Module::getActiveServer()
+{
+ return pqApplicationCore::instance()->getActiveServer();
+}
+
+
+/*!
+ \brief Creates PARAVIS preferences panel.
+*/
+void PVGUI_Module::createPreferences()
+{
+ // Paraview settings tab
+ int aParaViewSettingsTab = addPreference( tr( "TIT_PVIEWSETTINGS" ) );
+
+ setPreferenceProperty(aParaViewSettingsTab, "stretch", false );
+ int aPanel = addPreference(QString(), aParaViewSettingsTab, LightApp_Preferences::UserDefined, PARAVIS_MODULE_NAME, "");
+
+ 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<QVariant> aIndices;
+ QStringList aStrings;
+ aIndices<<0<<1<<2;
+ aStrings<<tr("PREF_SAVE_TYPE_0");
+ aStrings<<tr("PREF_SAVE_TYPE_1");
+ aStrings<<tr("PREF_SAVE_TYPE_2");
+ setPreferenceProperty(aSaveType, "strings", aStrings);
+ setPreferenceProperty(aSaveType, "indexes", aIndices);
+}
+
+/*!
+ \brief Creates ParaViS context menu popup
+*/
+void PVGUI_Module::contextMenuPopup(const QString& theClient, QMenu* theMenu, QString& theTitle)
+{
+ LightApp_Module::contextMenuPopup(theClient, theMenu, theTitle);
+
+ // Check if we are in Object Browser
+ SUIT_DataBrowser* ob = getApp()->objectBrowser();
+ bool isOBClient = (ob && theClient == ob->popupClientType());
+ if (!isOBClient) {
return;
}
- QFileInfo fi(profileFile);
- this->Implementation->DocumentationDir = fi.absolutePath();
+ // 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<SalomeApp_Study*>(getApp()->activeStudy());
+ if(!activeStudy) {
+ return;
+ }
- args.append(profileFile);
+ // 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;
+ }
- this->Implementation->AssistantClient->setArguments(args);
+ _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));
+ }
+ }
+ }
}
/*!
- \brief Slot to call the message handler with the critical message.
+ \brief. Show ParaView python trace.
*/
-void PVGUI_Module::assistantError( const QString& error )
+void PVGUI_Module::onShowTrace()
{
- qCritical(error.toAscii().data());
+ if (!myTraceWindow) {
+ myTraceWindow = new pqPythonScriptEditor(getApp()->desktop());
+ }
+ myTraceWindow->setText(getTraceString());
+ myTraceWindow->show();
+ myTraceWindow->raise();
+ myTraceWindow->activateWindow();
}
+
/*!
- \brief Slot to show the waiting state.
+ \brief. Re-initialize ParaView python trace.
*/
-void PVGUI_Module::onPreAccept()
+void PVGUI_Module::onRestartTrace()
{
- getApp()->desktop()->statusBar()->showMessage(tr("STB_PREACCEPT"));
- QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
+ stopTrace();
+ startTrace();
}
/*!
- \brief Slot to show the ready state.
+ \brief Save state under the module root object.
*/
-void PVGUI_Module::onPostAccept()
+void PVGUI_Module::onSaveMultiState()
{
- getApp()->desktop()->statusBar()->showMessage(tr("STB_POSTACCEPT"), 2000);
- QTimer::singleShot(0, this, SLOT(endWaitCursor()));
+ // 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 Slot to switch off wait cursor.
+ \brief Restore the selected state by merging with the current one.
*/
-void PVGUI_Module::endWaitCursor()
+void PVGUI_Module::onAddState()
{
- QApplication::restoreOverrideCursor();
+ loadSelectedState(false);
}
/*!
- \brief Returns the ParaView multi-view manager.
+ \brief Clean the current state and restore the selected one.
*/
-pqViewManager* PVGUI_Module::getMultiViewManager() const
+void PVGUI_Module::onCleanAddState()
{
- pqViewManager* aMVM = 0;
- if ( Implementation )
- aMVM = &Implementation->Core.multiViewManager();
- return aMVM;
+ loadSelectedState(true);
}
/*!
- \brief Processes QEvent::ActionAdded and QEvent::ActionRemoved from Lookmarks toolbar
- in order to register/unregister this action in/from QtxActionToolMgr.
+ \brief Rename the selected object.
*/
-bool PVGUI_Module::eventFilter( QObject* theObject, QEvent* theEvent )
+void PVGUI_Module::onRename()
{
- QToolBar* aTB = toolMgr()->toolBar(tr("TOOL_LOOKMARKS"));
- if ( theObject == aTB ) {
+ 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);
+ }
- if ( theEvent->type() == QEvent::ActionAdded ) {
- QList<QAction*> anActns = aTB->actions();
- for (int i = 0; i < anActns.size(); ++i)
- if ( toolMgr()->actionId(anActns.at(i)) == -1 ) {
- toolMgr()->setUpdatesEnabled(false);
- createTool( anActns.at(i), tr("TOOL_LOOKMARKS") );
- toolMgr()->setUpdatesEnabled(true);
- }
- }
-
- if ( theEvent->type() == QEvent::ActionRemoved ) {
- QList<QAction*> anActns = aTB->actions();
- QIntList aIDL = toolMgr()->idList();
- for (int i = 0; i < aIDL.size(); ++i) {
- if ( toolMgr()->action(aIDL.at(i))->parent() == aTB
- &&
- !anActns.contains( toolMgr()->action(aIDL.at(i)) ) ) {
- toolMgr()->setUpdatesEnabled(false);
- toolMgr()->unRegisterAction( aIDL.at(i) );
- toolMgr()->remove( aIDL.at(i), tr("TOOL_LOOKMARKS") );
- toolMgr()->setUpdatesEnabled(true);
- }
+ // 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();
+
}
-
- return QObject::eventFilter( theObject, theEvent );
}
/*!
- \brief Activate module.
- \param study current study
- \return \c true if activaion is done successfully or 0 to prevent
- activation on error
+ \brief Delete the selected objects.
*/
-bool PVGUI_Module::activateModule( SUIT_Study* study )
+void PVGUI_Module::onDelete()
{
- bool isDone = LightApp_Module::activateModule( study );
- if ( !isDone ) return false;
-
- if ( mySourcesMenuId != -1 ) menuMgr()->show(mySourcesMenuId);
- if ( myFiltersMenuId != -1 ) menuMgr()->show(myFiltersMenuId);
- setMenuShown( true );
- setToolShown( true );
-
- showView( true );
-
- toolMgr()->toolBar(tr("TOOL_LOOKMARKS"))->installEventFilter(this);
+ 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();
+ }
+}
- // Make default server connection
- if ( Implementation )
- Implementation->Core.makeDefaultConnectionIfNoneExists();
+/*!
+ * \brief Slot called everytime the Python trace is pushed onto the CORBA engine.
+ */
+void PVGUI_Module::onPushTraceTimer()
+{
+ //MESSAGE("onPushTraceTimer(): Pushing trace to engine...");
+ GetEngine()->PutPythonTraceStringToEngine(getTraceString().toStdString().c_str());
+}
- return isDone;
+/*!
+ \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;
}
/*!
- \brief Deactivate module.
- \param study current study
- \return \c true if deactivaion is done successfully or 0 to prevent
- deactivation on error
+ \brief Load selected paraview state
+
+ If toClear == true, the current state will be cleared
*/
-bool PVGUI_Module::deactivateModule( SUIT_Study* study )
+void PVGUI_Module::loadSelectedState(bool toClear)
{
- toolMgr()->toolBar(tr("TOOL_LOOKMARKS"))->removeEventFilter(this);
+ QString fileName;
- // hide menus
- menuMgr()->hide(mySourcesMenuId);
- menuMgr()->hide(myFiltersMenuId);
- setMenuShown( false );
- setToolShown( false );
+ 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;
+ }
- saveDockWidgetsState();
+ // 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;
+ }
- return LightApp_Module::deactivateModule( study );
+ // 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"));
+ }
}
/*!
#endif // WNT
extern "C" {
+
+ bool flag = false;
PVGUI_EXPORT CAM_Module* createModule() {
return new PVGUI_Module();
}
+
+ PVGUI_EXPORT char* getModuleVersion() {
+ return (char*)PARAVIS_VERSION_STR;
+ }
}