X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FPVGUI%2FPVGUI_Module.cxx;h=99221e8237f74f649a4113a2a186712f3e438981;hb=1eb23ff388682331691712a69cd96107c5a4fef6;hp=9551b0b747bb363d73f4fb663df360c346290161;hpb=3637a467388397b03c104e17f12474cdfb02e1d9;p=modules%2Fparavis.git diff --git a/src/PVGUI/PVGUI_Module.cxx b/src/PVGUI/PVGUI_Module.cxx index 9551b0b7..99221e82 100644 --- a/src/PVGUI/PVGUI_Module.cxx +++ b/src/PVGUI/PVGUI_Module.cxx @@ -1,7 +1,6 @@ // 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-2012 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 @@ -21,21 +20,53 @@ // // File : PVGUI_Module.cxx // Author : Julia DOROVSKIKH -// +#include // E.A. must be included before Python.h to fix compilation on windows +#ifdef HAVE_FINITE +#undef HAVE_FINITE // VSR: avoid compilation warning on Linux : "HAVE_FINITE" redefined +#endif +#include // Python first #include "PVGUI_Module.h" -#include "PVGUI_Module_impl.h" -#include "PVGUI_ProcessModuleHelper.h" + +#include "SALOMEconfig.h" +#ifdef WITH_VISU +#include CORBA_CLIENT_HEADER(VISU_Gen) +#endif +#include CORBA_SERVER_HEADER(SALOMEDS) + + +#include "PARAVIS_Gen_i.hh" + +#include "PV_Tools.h" + #include "PVGUI_ViewModel.h" #include "PVGUI_ViewManager.h" #include "PVGUI_ViewWindow.h" +#include "PVGUI_Tools.h" +#include "PVGUI_ParaViewSettingsPane.h" +#include "PVGUI_OutputWindowAdapter.h" +#include #include #include #include #include -#include -#include +#include +#include + +// SALOME Includes +#include "SALOME_LifeCycleCORBA.hxx" +#include "SALOMEDS_SObject.hxx" + +#include "LightApp_SelectionMgr.h" +#include "LightApp_NameDlg.h" + +#include +#include +#include +#include +#include + #include #include @@ -47,28 +78,58 @@ #include #include #include +#include #include #include #include #include #include +#include +#include +#include +#include #include -#include +#include #include -#include #include #include #include -#include #include -#include -#include #include #include -#include -#include +#include +#include +#include #include +#include +#include +#include +#include +#include +#include +//#include +#include "pqInterfaceTracker.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include CORBA_SERVER_HEADER(SALOME_ModuleCatalog) /* * Make sure all the kits register their classes with vtkInstantiator. @@ -90,72 +151,207 @@ #include #include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include //---------------------------------------------------------------------------- -// 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 *); +pqPVApplicationCore* PVGUI_Module::MyCoreApp = 0; +//PVGUI_OutputWindowAdapter* PVGUI_Module::pqImplementation::OutputWindowAdapter = 0; +//QPointer PVGUI_Module::pqImplementation::helpWindow = 0; -//---------------------------------------------------------------------------- -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; +PVGUI_Module* ParavisModule = 0; + +/*! + \mainpage + +

Building and installing PARAVIS

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

ParaView GUI integration

+

ParaView GUI integration overview

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

ParaView client initalization

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

Multi-view manager

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

ParaView plugins

+ ParaView server and client plugins are managed by %pqMainWindowCore slots that has full access to PARAVIS menus and toolbars. + As a result they appears automatically in PARAVIS menus and toolbars if loaded successfully. +*/ /*! \class PVGUI_Module - \brief Implementation of light (no-CORBA-engine) + \brief Implementation SALOME module wrapping ParaView GUI. */ + +/* + Fix for the issue 21730: [CEA 596] Slice of polyhedron in PARAVIS returns no cell. + Wrap vtkEDFCutter filter. +*/ + +extern "C" void vtkEDFCutterCS_Initialize(vtkClientServerInterpreter*); +static void vtkEDFHelperInit(); + +void vtkEDFHelperInit(vtkClientServerInterpreter* interp){ + vtkEDFCutterCS_Initialize(interp); +} + +void vtkEDFHelperInit() { + vtkClientServerInterpreterInitializer::GetInitializer()-> + RegisterCallback(&vtkEDFHelperInit); +} + + + _PTR(SComponent) + ClientFindOrCreateParavisComponent(_PTR(Study) theStudyDocument) + { + _PTR(SComponent) aSComponent = theStudyDocument->FindComponent("PARAVIS"); + if (!aSComponent) { + _PTR(StudyBuilder) aStudyBuilder = theStudyDocument->NewBuilder(); + aStudyBuilder->NewCommand(); + int aLocked = theStudyDocument->GetProperties()->IsLocked(); + if (aLocked) theStudyDocument->GetProperties()->SetLocked(false); + aSComponent = aStudyBuilder->NewComponent("PARAVIS"); + _PTR(GenericAttribute) anAttr = + aStudyBuilder->FindOrCreateAttribute(aSComponent, "AttributeName"); + _PTR(AttributeName) aName (anAttr); + + CORBA::ORB_var anORB = PARAVIS::PARAVIS_Gen_i::GetORB(); + 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( "PARAVIS" ); + 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"); + + + PARAVIS::PARAVIS_Gen_var aPARAVIS = PARAVIS::PARAVIS_Gen_i::GetParavisGenImpl()->_this(); + + aStudyBuilder->DefineComponentInstance(aSComponent, aPARAVIS->GetIOR()); + if (aLocked) theStudyDocument->GetProperties()->SetLocked(true); + aStudyBuilder->CommitCommand(); + } + return aSComponent; + } + +/*! + 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" ), + // Implementation( 0 ), mySelectionControlsTb( -1 ), mySourcesMenuId( -1 ), - myFiltersMenuId( -1 ) + myFiltersMenuId( -1 ), + myMacrosMenuId(-1), + myToolbarsMenuId(-1), + myRecentMenuId(-1), + myOldMsgHandler(0), + myTraceWindow(0), + myStateCounter(0) { +#ifdef HAS_PV_DOC + Q_INIT_RESOURCE( PVGUI ); +#endif + ParavisModule = this; + + // Clear old macros + 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 aStr, aDestFiles) { + aDestDir.remove(aStr); + } } /*! @@ -165,13 +361,20 @@ PVGUI_Module::~PVGUI_Module() { } + + /*! \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 ); + SalomeApp_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 :) @@ -186,25 +389,243 @@ void PVGUI_Module::initialize( CAM_Application* app ) pvInit(); // Create GUI elements (menus, toolbars, dock widgets) - if ( !Implementation ){ - LightApp_Application* anApp = getApp(); + //if ( !Implementation ){ + SalomeApp_Application* anApp = getApp(); + SUIT_Desktop* aDesktop = anApp->desktop(); + + // connect(aDesktop, SIGNAL() + + // Remember current state of desktop toolbars + QList foreignToolbars = aDesktop->findChildren(); // Simulate ParaView client main window - Implementation = new pqImplementation( anApp->desktop() ); + //Implementation = new pqImplementation( aDesktop ); setupDockWidgets(); pvCreateActions(); - pvCreateMenus(); pvCreateToolBars(); - - setupDockWidgetsContextMenu(); + pvCreateMenus(); + + // new pqParaViewBehaviors(anApp->desktop(), this); + // Has to be replaced in order to exclude using of pqQtMessageHandlerBehaviour + // Start pqParaViewBehaviors + // Register ParaView interfaces. + //pqPluginManager* pgm = pqApplicationCore::instance()->getPluginManager(); + pqInterfaceTracker* pgm = pqApplicationCore::instance()->interfaceTracker(); + + // * adds support for standard paraview views. + pgm->addInterface(new pqStandardViewModules(pgm)); + pgm->addInterface(new pqStandardSummaryPanelImplementation(pgm)); + + // Load plugins distributed with application. + pqApplicationCore::instance()->loadDistributedPlugins(); + + // Define application behaviors. + //new pqQtMessageHandlerBehavior(this); + new pqDataTimeStepBehavior(this); + new pqViewFrameActionsBehavior(this); + new pqSpreadSheetVisibilityBehavior(this); + new pqPipelineContextMenuBehavior(this); + new pqDefaultViewBehavior(this); + new pqAlwaysConnectedBehavior(this); + new pqPVNewSourceBehavior(this); + new pqDeleteBehavior(this); + new pqUndoRedoBehavior(this); + new pqCrashRecoveryBehavior(this); + new pqAutoLoadPluginXMLBehavior(this); + new pqPluginDockWidgetsBehavior(aDesktop); + //new pqVerifyRequiredPluginBehavior(this); + new pqPluginActionGroupBehavior(aDesktop); + //new pqFixPathsInStateFilesBehavior(this); + new pqCommandLineOptionsBehavior(this); + new pqPersistentMainWindowStateBehavior(aDesktop); + new pqObjectPickingBehavior(aDesktop); + new pqCollaborationBehavior(this); + + // Setup quick-launch shortcuts. + QShortcut *ctrlSpace = new QShortcut(Qt::CTRL + Qt::Key_Space, aDesktop); + QObject::connect(ctrlSpace, SIGNAL(activated()), + pqApplicationCore::instance(), SLOT(quickLaunch())); + QShortcut *altSpace = new QShortcut(Qt::ALT + Qt::Key_Space, aDesktop); + QObject::connect(altSpace, SIGNAL(activated()), + pqApplicationCore::instance(), SLOT(quickLaunch())); + // End pqParaViewBehaviors + + + SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); + QString aPath = resMgr->stringValue("resources", "PARAVIS", QString()); + if (!aPath.isNull()) { + MyCoreApp->loadConfiguration(aPath + QDir::separator() + "ParaViewFilters.xml"); + MyCoreApp->loadConfiguration(aPath + QDir::separator() + "ParaViewReaders.xml"); + MyCoreApp->loadConfiguration(aPath + QDir::separator() + "ParaViewSources.xml"); + MyCoreApp->loadConfiguration(aPath + QDir::separator() + "ParaViewWriters.xml"); + } + + // Force creation of engine + PARAVIS::GetParavisGen(this); + updateObjBrowser(); + + // Find created toolbars + QCoreApplication::processEvents(); + + QList allToolbars = aDesktop->findChildren(); + foreach(QToolBar* aBar, allToolbars) { + if (!foreignToolbars.contains(aBar)) { + myToolbars[aBar] = true; + myToolbarBreaks[aBar] = false; + aBar->setVisible(false); + aBar->toggleViewAction()->setVisible(false); + } + } + //} + + updateMacros(); + + // we need to start trace after connection is done + connect(pqApplicationCore::instance()->getObjectBuilder(), SIGNAL(finishedAddingServer(pqServer*)), + this, SLOT(onFinishedAddingServer(pqServer*))); + + connect(pqApplicationCore::instance()->getObjectBuilder(), SIGNAL(dataRepresentationCreated(pqDataRepresentation*)), + this, SLOT(onDataRepresentationCreated(pqDataRepresentation*))); + + + SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr(); + bool isStop = aResourceMgr->booleanValue( "PARAVIS", "stop_trace", false ); + // start timer to activate trace in a proper moment + if(!isStop) + startTimer( 50 ); + + this->VTKConnect = vtkEventQtSlotConnect::New(); + vtkProcessModule* pm = vtkProcessModule::GetProcessModule(); + + this->VTKConnect->Connect(pm, vtkCommand::StartEvent, + this, SLOT(onStartProgress())); + this->VTKConnect->Connect(pm, vtkCommand::EndEvent, + this, SLOT(onEndProgress())); + + connect(&pqActiveObjects::instance(), + SIGNAL(representationChanged(pqRepresentation*)), + this, SLOT(onRepresentationChanged(pqRepresentation*))); +} - // Now that we're ready, initialize everything ... - Implementation->Core.initializeStates(); +void PVGUI_Module::onStartProgress() +{ + QApplication::setOverrideCursor(Qt::WaitCursor); +} + +void PVGUI_Module::onEndProgress() +{ + QApplication::restoreOverrideCursor(); +} + +void PVGUI_Module::onFinishedAddingServer(pqServer* /*server*/) +{ + SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr(); + bool isStop = aResourceMgr->booleanValue( "PARAVIS", "stop_trace", false ); + if(!isStop) + startTimer( 50 ); +} + +void PVGUI_Module::onDataRepresentationCreated(pqDataRepresentation* data) { + if(!data) + return; + + if(!data->getLookupTable()) + return; + + SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr(); + if(!aResourceMgr) + return; + + bool visible = aResourceMgr->booleanValue( "PARAVIS", "show_color_legend", false ); + pqLookupTableManager* lut_mgr = pqApplicationCore::instance()->getLookupTableManager(); + + if(lut_mgr) { + lut_mgr->setScalarBarVisibility(data,visible); } } +void PVGUI_Module::onVariableChanged(pqVariableType t, const QString) { + + pqDisplayColorWidget* colorWidget = qobject_cast(sender()); + if( !colorWidget ) + return; + + if( t == VARIABLE_TYPE_NONE ) + return; + + pqDataRepresentation* data = colorWidget->getRepresentation(); + + if( !data->getLookupTable() ) + return; + + SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr(); + + if(!aResourceMgr) + return; + + bool visible = aResourceMgr->booleanValue( "PARAVIS", "show_color_legend", false ); + + if(!visible) + return; + + pqLookupTableManager* lut_mgr = pqApplicationCore::instance()->getLookupTableManager(); + + if(lut_mgr) { + lut_mgr->setScalarBarVisibility(data,visible); + } + +} + + +/*! + \brief Launches a tracing of current server +*/ +void PVGUI_Module::timerEvent(QTimerEvent* te ) +{ +#ifndef WNT + PyInterp_Dispatcher* aDispatcher = PyInterp_Dispatcher::Get(); + if ( !aDispatcher->IsBusy() ) { + pqPythonManager* manager = qobject_cast + ( pqApplicationCore::instance()->manager( "PYTHON_MANAGER" ) ); + if ( manager ) { + pqPythonDialog* pyDiag = manager->pythonShellDialog(); + if ( pyDiag ) { + pqPythonShell* shell = pyDiag->shell(); + if ( shell ) { + QString script = "from paraview import smtrace\nsmtrace.start_trace()\n"; + shell->executeScript(script); + killTimer( te->timerId() ); + } + } + } + } +#endif +} + +void PVGUI_Module::updateMacros() +{ + pqPythonManager* aPythonManager = pqPVApplicationCore::instance()->pythonManager(); + if(!aPythonManager) { + return; + } + + QString aRootDir = getenv("PARAVIS_ROOT_DIR"); + + QString aSourcePath = aRootDir + "/bin/salome/Macro"; + + QStringList aFilter; + aFilter << "*.py"; + + QDir aSourceDir(aSourcePath); + QStringList aSourceFiles = aSourceDir.entryList(aFilter, QDir::Files); + foreach (QString aStr, aSourceFiles) { + aPythonManager->addMacro(aSourcePath + "/" + aStr); + } +} + + /*! \brief Get list of compliant dockable GUI elements \param m map to be filled in ("type":"default_position") @@ -217,87 +638,78 @@ void PVGUI_Module::windows( QMap& m ) const m.insert( LightApp_Application::WT_LogWindow, Qt::BottomDockWidgetArea ); } -/*! - \brief Create custom popup menu selection object. - \return new selected object -*/ -/*LightApp_Selection* PVGUI_Module::createSelection() const -{ - return new PVGUI_Selection(); -}*/ - -/*! - \brief Create data model. - \return module specific data model -*/ -/*CAM_DataModel* PVGUI_Module::createDataModel() -{ - return new PVGUI_DataModel( this ); -}*/ - /*! \brief Static method, performs initialization of ParaView session. \return \c true if ParaView has been initialized successfully, otherwise false */ bool PVGUI_Module::pvInit() { - if ( !pqImplementation::myPVMain ){ + // if ( !pqImplementation::Core ){ + if ( ! MyCoreApp) { // Obtain command-line arguments - // Workaround to avoid pqOptions messages: pass only the executable path to vtkPVMain int argc = 0; + char** argv = 0; + QString aOptions = getenv("PARAVIS_OPTIONS"); + QStringList aOptList = aOptions.split(":", QString::SkipEmptyParts); + argv = new char*[aOptList.size() + 1]; 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() ); + argv[0] = (args.size() > 0)? strdup(args[0].toLatin1().constData()) : strdup("paravis"); + argc++; - vtkPVMain::SetInitializeMPI(0); // pvClient never runs with MPI. - vtkPVMain::Initialize(&argc, &argv); // Perform any initializations. - - // TODO: Set plugin dir from preferences - //QApplication::setLibraryPaths(QStringList(dir.absolutePath())); + foreach (QString aStr, aOptList) { + argv[argc] = strdup( aStr.toLatin1().constData() ); + argc++; + } + MyCoreApp = new pqPVApplicationCore (argc, argv); + if (MyCoreApp->getOptions()->GetHelpSelected() || + MyCoreApp->getOptions()->GetUnknownArgument() || + MyCoreApp->getOptions()->GetErrorMessage() || + MyCoreApp->getOptions()->GetTellVersion()) { + return false; + } - pqImplementation::myPVMain = vtkPVMain::New(); - if ( !pqImplementation::myPVOptions ) - pqImplementation::myPVOptions = pqOptions::New(); - if ( !pqImplementation::myPVHelper ) - pqImplementation::myPVHelper = PVGUI_ProcessModuleHelper::New(); + // Not sure why this is needed. Andy added this ages ago with comment saying + // needed for Mac apps. Need to check that it's indeed still required. + QDir dir(QApplication::applicationDirPath()); + dir.cdUp(); + dir.cd("Plugins"); + QApplication::addLibraryPath(dir.absolutePath()); + // Load required application plugins. + QString plugin_string = ""; + QStringList plugin_list = plugin_string.split(';',QString::SkipEmptyParts); + pqBrandPluginsLoader loader; + if (loader.loadPlugins(plugin_list) == false) { + printf("Failed to load required plugins for this application\n"); + return false; + } - pqImplementation::myPVOptions->SetProcessType(vtkPVOptions::PVCLIENT); + // Load optional plugins. + plugin_string = ""; + plugin_list = plugin_string.split(';',QString::SkipEmptyParts); + loader.loadPlugins(plugin_list, true); //quietly skip not-found plugins. - // 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); - } + // End of Initializer code + vtkOutputWindow::SetInstance(PVGUI_OutputWindowAdapter::New()); + + new pqTabbedMultiViewWidget(); // it registers as "MULTIVIEW_WIDGET on creation + + for (int i = 0; i < argc; i++) + free(argv[i]); delete[] argv; - return !ret; } return true; } -/*! - \brief Static method, cleans up ParaView session at application exit. -*/ -void PVGUI_Module::pvShutdown() -{ - // TODO... -} - /*! \brief Shows (toShow = true) or hides ParaView view window */ void PVGUI_Module::showView( bool toShow ) { - LightApp_Application* anApp = getApp(); - PVGUI_ViewManager* viewMgr = dynamic_cast( anApp->getViewManager( PVGUI_Viewer::Type(), false ) ); + SalomeApp_Application* anApp = getApp(); + PVGUI_ViewManager* viewMgr = + dynamic_cast( anApp->getViewManager( PVGUI_Viewer::Type(), false ) ); if ( !viewMgr ) { viewMgr = new PVGUI_ViewManager( anApp->activeStudy(), anApp->desktop() ); anApp->addViewManager( viewMgr ); @@ -308,431 +720,827 @@ void PVGUI_Module::showView( bool toShow ) PVGUI_ViewWindow* pvWnd = dynamic_cast( viewMgr->getActiveView() ); if ( !pvWnd ) { pvWnd = dynamic_cast( viewMgr->createViewWindow() ); - pvWnd->setMultiViewManager( &Implementation->Core.multiViewManager() ); } 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 Returns the ParaView multi-view manager. */ -void PVGUI_Module::onDeleteAll() +pqTabbedMultiViewWidget* PVGUI_Module::getMultiViewManager() const { - pqObjectBuilder* builder = pqApplicationCore::instance()->getObjectBuilder(); - Implementation->Core.getApplicationUndoStack()->beginUndoSet("Delete All"); - builder->destroyPipelineProxies(); - Implementation->Core.getApplicationUndoStack()->endUndoSet(); + return qobject_cast(pqApplicationCore::instance()->manager("MULTIVIEW_WIDGET")); +} + + +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 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 ); + + bool isDone = SalomeApp_Module::activateModule( study ); + if ( !isDone ) return false; + + showView( true ); + if ( mySourcesMenuId != -1 ) menuMgr()->show(mySourcesMenuId); + if ( myFiltersMenuId != -1 ) menuMgr()->show(myFiltersMenuId); + if ( myFiltersMenuId != -1 ) menuMgr()->show(myMacrosMenuId); + if ( myFiltersMenuId != -1 ) menuMgr()->show(myToolbarsMenuId); + setMenuShown( true ); + setToolShown( true ); + + restoreDockWidgetsState(); + + QMenu* aMenu = menuMgr()->findMenu( myRecentMenuId ); + if(aMenu) { + QList anActns = aMenu->actions(); + for (int i = 0; i < anActns.size(); ++i) { + QAction* a = anActns.at(i); + 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( - pqActiveView::instance().current()); - action(ShowCenterId)->setChecked( renView ? renView->getCenterAxesVisibility() : false); - action(ShowCenterId)->blockSignals(false); + QMenu* aMenu = menuMgr()->findMenu( myRecentMenuId ); + if(aMenu) { + QList anActns = aMenu->actions(); + for (int i = 0; i < anActns.size(); ++i) { + QAction* a = anActns.at(i); + if(a) + a->setVisible(false); + } + } + + QList aStreamingViews = application()->desktop()->findChildren("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); + + return SalomeApp_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')); + pqApplicationCore::instance()->settings()->sync(); + int aAppsNb = SUIT_Session::session()->applications().size(); + if (aAppsNb == 1) { + deleteTemporaryFiles(); + MyCoreApp->deleteLater(); + } + CAM_Module::onApplicationClosed(theApp); } + /*! - \brief Slot to manage the plaing process of animation. + \brief Called when study is closed. + + Removes data model from the \a study. + + \param study study being closed */ -void PVGUI_Module::onPlaying( bool playing ) +void PVGUI_Module::studyClosed(SUIT_Study* study) { - 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"); - } + clearParaviewState(); - Implementation->Core.setSelectiveEnabledState(!playing); + SalomeApp_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(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::GetParavisGen(this)->ComponentDataType()); + if(!paravisComp) { + return; + } + + _PTR(ChildIterator) anIter(studyDS->NewChildIterator(paravisComp)); + for (; anIter->More(); anIter->Next()) { + _PTR(SObject) aSObj = anIter->Value(); + _PTR(GenericAttribute) anAttr; + if (!aSObj->FindAttribute(anAttr, "AttributeLocalID")) { + continue; + } + _PTR(AttributeLocalID) anID(anAttr); + if (anID->Value() == PVSTATEID) { + myStateCounter++; + } + } } /*! - \brief 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 = PARAVIS::GetParavisGen(this)->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(); - - 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); - } + QStringList aFiles; + aFiles<( + pqApplicationCore::instance()->manager("PYTHON_MANAGER")); + if (manager) { + pqPythonDialog* pyDiag = manager->pythonShellDialog(); + if (pyDiag) { + pyDiag->runString(script); + } } - //cout << " Failed" << endl; - } - return app_dir + QDir::separator() + appName; +#endif } /*! - \brief Initialized an assistant client. + \brief Returns trace string */ -void PVGUI_Module::makeAssistant() +static const QString MYReplaceStr("paraview.simple"); +static const QString MYReplaceImportStr("except: from pvsimple import *"); +QString PVGUI_Module::getTraceString() { - if(this->Implementation->AssistantClient) - 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; + QString traceString; +#ifndef WNT + pqPythonManager* manager = qobject_cast( + pqApplicationCore::instance()->manager("PYTHON_MANAGER")); + if (manager) { + pqPythonDialog* pyDiag = manager->pythonShellDialog(); + if (pyDiag) { + pyDiag->runString("from paraview import smtrace\n" + "__smtraceString = smtrace.get_trace_string()\n"); + pyDiag->shell()->makeCurrent(); + PyObject* main_module = PyImport_AddModule((char*)"__main__"); + PyObject* global_dict = PyModule_GetDict(main_module); + PyObject* string_object = PyDict_GetItemString(global_dict, "__smtraceString"); + char* string_ptr = string_object ? PyString_AsString(string_object) : 0; + if (string_ptr) { + traceString = string_ptr; + } + pyDiag->shell()->releaseControl(); + } } - - if(profileFile.isEmpty() && getenv("PARAVIEW_HELP")) { - // not bundled, ask for help - args.append(getenv("PARAVIEW_HELP")); + if ((!traceString.isNull()) && traceString.length() != 0) { + int aPos = traceString.indexOf(MYReplaceStr); + while (aPos != -1) { + traceString = traceString.replace(aPos, MYReplaceStr.length(), "pvsimple"); + aPos = traceString.indexOf(MYReplaceStr, aPos); + } + int aImportPos = traceString.indexOf(MYReplaceImportStr); + if(aImportPos != -1) + { + traceString = traceString.replace(aImportPos, MYReplaceImportStr.length(), "except:\n import pvsimple\n from pvsimple import *"); + } } - 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; +#endif + return traceString; +} + +/*! + \brief Saves trace string to disk file +*/ +void PVGUI_Module::saveTrace(const char* theName) +{ + QFile file(theName); + if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { + MESSAGE( "Could not open file:" << theName ); return; } + QTextStream out(&file); + out << getTraceString(); + file.close(); +} - QFileInfo fi(profileFile); - this->Implementation->DocumentationDir = fi.absolutePath(); - - args.append(profileFile); +/*! + \brief Saves ParaView state to a disk file +*/ +void PVGUI_Module::saveParaviewState(const char* theFileName) +{ + pqApplicationCore::instance()->saveState(theFileName); +} - this->Implementation->AssistantClient->setArguments(args); +/*! + \brief Delete all objects for Paraview Pipeline Browser +*/ +void PVGUI_Module::clearParaviewState() +{ + QAction* deleteAllAction = action(DeleteAllId); + if (deleteAllAction) { + deleteAllAction->activate(QAction::Trigger); + } } /*! - \brief Slot to call the message handler with the critical message. + \brief Restores ParaView state from a disk file + + If toClear == true, the current ojects will be deleted */ -void PVGUI_Module::assistantError( const QString& error ) +void PVGUI_Module::loadParaviewState(const char* theFileName) { - qCritical(error.toAscii().data()); + pqApplicationCore::instance()->loadState(theFileName, getActiveServer()); } /*! - \brief Slot to show the waiting state. + \brief Imports MED data from VISU module by data entry */ -void PVGUI_Module::onPreAccept() +void PVGUI_Module::onImportFromVisu(QString theEntry) { - getApp()->desktop()->statusBar()->showMessage(tr("STB_PREACCEPT")); - QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); +#ifdef WITH_VISU + SUIT_OverrideCursor aWaitCursor; + + // get active study + SalomeApp_Study* activeStudy = dynamic_cast(application()->activeStudy()); + if(!activeStudy) return; + + // get SALOMEDS client study + _PTR(Study) aStudy = activeStudy->studyDS(); + if(!aStudy) return; + + // find VISU component in a study + _PTR(SComponent) aVisuComp = aStudy->FindComponent( "VISU" ); + if(!aVisuComp) return; + + // get SObject client by entry + _PTR(SObject) aSObj = aStudy->FindObjectID(qPrintable(theEntry)); + if (!aSObj) return; + + // get CORBA SObject + SALOMEDS_SObject* aSObject = _CAST(SObject, aSObj); + if ( !aSObject ) return; + + // load VISU engine + SALOME_NamingService* aNamingService = SalomeApp_Application::namingService(); + SALOME_LifeCycleCORBA aLCC(aNamingService); + + Engines::EngineComponent_var aComponent = aLCC.FindOrLoad_Component("FactoryServer","VISU"); + VISU::VISU_Gen_var aVISU = VISU::VISU_Gen::_narrow(aComponent); + if(CORBA::is_nil(aVISU)) return; + + _PTR(StudyBuilder) aStudyBuilder = aStudy->NewBuilder(); + aStudyBuilder->LoadWith( aVisuComp, SalomeApp_Application::orb()->object_to_string(aVISU) ); + + // get VISU result object + CORBA::Object_var aResultObject = aSObject->GetObject(); + if (CORBA::is_nil(aResultObject)) return; + VISU::Result_var aResult = VISU::Result::_narrow( aResultObject ); + if (CORBA::is_nil(aResult)) return; + + // export VISU result to the MED file + std::string aTmpDir = SALOMEDS_Tool::GetTmpDir(); + std::string aFileName = aSObject->GetName(); + std::string aFilePath = aTmpDir + aFileName; + + if (aResult->ExportMED(aFilePath.c_str())) { + openFile(aFilePath.c_str()); + myTemporaryFiles.append(QString(aFilePath.c_str())); + } +#else + MESSAGE("Visu module is not found."); +#endif } /*! - \brief Slot to show the ready state. + \brief Deletes temporary files created during import operation from VISU */ -void PVGUI_Module::onPostAccept() +void PVGUI_Module::deleteTemporaryFiles() { - getApp()->desktop()->statusBar()->showMessage(tr("STB_POSTACCEPT"), 2000); - QTimer::singleShot(0, this, SLOT(endWaitCursor())); + foreach(QString aFile, myTemporaryFiles) { + if (QFile::exists(aFile)) { + QFile::remove(aFile); + } + } } + /*! - \brief Slot to switch off wait cursor. + \brief Returns current active ParaView server */ -void PVGUI_Module::endWaitCursor() +pqServer* PVGUI_Module::getActiveServer() { - QApplication::restoreOverrideCursor(); + return pqApplicationCore::instance()->getActiveServer(); } + /*! - \brief Returns the ParaView multi-view manager. + \brief Creates PARAVIS preference pane */ -pqViewManager* PVGUI_Module::getMultiViewManager() const +void PVGUI_Module::createPreferences() { - pqViewManager* aMVM = 0; - if ( Implementation ) - aMVM = &Implementation->Core.multiViewManager(); - return aMVM; + // Paraview settings tab + int aParaViewSettingsTab = addPreference( tr( "TIT_PVIEWSETTINGS" ) ); + int aPanel = addPreference(QString(), aParaViewSettingsTab, LightApp_Preferences::UserDefined, "PARAVIS", ""); + setPreferenceProperty(aPanel, "content", (qint64)(new PVGUI_ParaViewSettingsPane())); + + // Paravis settings tab + int aParaVisSettingsTab = addPreference( tr( "TIT_PVISSETTINGS" ) ); + addPreference( tr( "PREF_STOP_TRACE" ), aParaVisSettingsTab, LightApp_Preferences::Bool, "PARAVIS", "stop_trace"); + + int aSaveType = addPreference(tr( "PREF_SAVE_TYPE_LBL" ), aParaVisSettingsTab, + LightApp_Preferences::Selector, + "PARAVIS", "savestate_type"); + QList aIndices; + QStringList aStrings; + aIndices<<0<<1<<2; + aStrings<toolBar(tr("TOOL_LOOKMARKS")); - if ( theObject == aTB ) { + SalomeApp_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; + } + + // 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()); - if ( theEvent->type() == QEvent::ActionAdded ) { - QList 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); - } + // Get active study + SalomeApp_Study* activeStudy = + dynamic_cast(getApp()->activeStudy()); + if(!activeStudy) { + return; } - if ( theEvent->type() == QEvent::ActionRemoved ) { - QList 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); - } + // Get SALOMEDS client study + _PTR(Study) studyDS = activeStudy->studyDS(); + if(!studyDS) { + return; + } + + QString paravisDataType(PARAVIS::GetParavisGen(this)->ComponentDataType()); + if(activeStudy && activeStudy->isComponent(entry) && + activeStudy->componentDataType(entry) == paravisDataType) { + // ParaViS module object + theMenu->addSeparator(); + theMenu->addAction(action(SaveStatePopupId)); + } + else { + // Try to get state object + _PTR(SObject) stateSObj = + studyDS->FindObjectID(entry.toLatin1().constData()); + if (!stateSObj) { + return; + } + + // Check local id + _PTR(GenericAttribute) anAttr; + if (!stateSObj->FindAttribute(anAttr, "AttributeLocalID")) { + return; + } + + _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)); } } - } +} - return QObject::eventFilter( theObject, theEvent ); +void PVGUI_Module::onShowTrace() +{ + if (!myTraceWindow) { + myTraceWindow = new pqPythonScriptEditor(getApp()->desktop()); + } + myTraceWindow->setText(getTraceString()); + myTraceWindow->show(); + myTraceWindow->raise(); + myTraceWindow->activateWindow(); } /*! - \brief Activate module. - \param study current study - \return \c true if activaion is done successfully or 0 to prevent - activation on error + \brief Show ParaView view. */ -bool PVGUI_Module::activateModule( SUIT_Study* study ) +void PVGUI_Module::onNewParaViewWindow() { - bool isDone = LightApp_Module::activateModule( study ); - if ( !isDone ) return false; + showView(true); +} - showView( true ); +/*! + \brief Save state under the module root object. +*/ +void PVGUI_Module::onSaveMultiState() +{ + // Create state study object + + // Get SALOMEDS client study + _PTR(Study) studyDS = PARAVIS::GetCStudy(this); + if(!studyDS) { + return; + } + + _PTR(SComponent) paravisComp = + studyDS->FindComponent(PARAVIS::GetParavisGen(this)->ComponentDataType()); + if(!paravisComp) { + return; + } - if ( mySourcesMenuId != -1 ) menuMgr()->show(mySourcesMenuId); - if ( myFiltersMenuId != -1 ) menuMgr()->show(myFiltersMenuId); - setMenuShown( true ); - setToolShown( true ); + // 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); - toolMgr()->toolBar(tr("TOOL_LOOKMARKS"))->installEventFilter(this); + _PTR(StudyBuilder) studyBuilder = studyDS->NewBuilder(); + _PTR(SObject) newSObj = studyBuilder->NewObject(paravisComp); - // Make default server connection - if ( Implementation ) - Implementation->Core.makeDefaultConnectionIfNoneExists(); + // Set name + _PTR(GenericAttribute) anAttr; + anAttr = studyBuilder->FindOrCreateAttribute(newSObj, "AttributeName"); + _PTR(AttributeName) nameAttr(anAttr); + + nameAttr->SetValue(stateName.toLatin1().constData()); - restoreDockWidgetsState(); + // Set local id + anAttr = studyBuilder->FindOrCreateAttribute(newSObj, "AttributeLocalID"); + _PTR(AttributeLocalID) localIdAttr(anAttr); + + localIdAttr->SetValue(PVSTATEID); - return isDone; -} + // 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 Deactivate module. - \param study current study - \return \c true if deactivaion is done successfully or 0 to prevent - deactivation on error + \brief Restore the selected state by merging with the current one. */ -bool PVGUI_Module::deactivateModule( SUIT_Study* study ) +void PVGUI_Module::onAddState() { - toolMgr()->toolBar(tr("TOOL_LOOKMARKS"))->removeEventFilter(this); + loadSelectedState(false); +} - showView( false ); +/*! + \brief Clean the current state and restore the selected one. +*/ +void PVGUI_Module::onCleanAddState() +{ + loadSelectedState(true); +} - // hide menus - menuMgr()->hide(mySourcesMenuId); - menuMgr()->hide(myFiltersMenuId); - setMenuShown( false ); - setToolShown( false ); +/*! + \brief Rename the selected object. +*/ +void PVGUI_Module::onRename() +{ + LightApp_SelectionMgr* aSelectionMgr = getApp()->selectionMgr(); + SALOME_ListIO aListIO; + aSelectionMgr->selectedObjects(aListIO); + + if (aListIO.Extent() == 1 && aListIO.First()->hasEntry()) { + std::string entry = aListIO.First()->getEntry(); + + // Get SALOMEDS client study + _PTR(Study) studyDS = PARAVIS::GetCStudy(this); + if(!studyDS) { + return; + } + + // Unlock the study if it is locked + bool isLocked = studyDS->GetProperties()->IsLocked(); + if (isLocked) { + studyDS->GetProperties()->SetLocked(false); + } + + // Rename the selected state object + _PTR(SObject) stateSObj = studyDS->FindObjectID(entry); + if (!stateSObj) { + return; + } + + _PTR(GenericAttribute) anAttr; + if (stateSObj->FindAttribute(anAttr, "AttributeName")) { + _PTR(AttributeName) nameAttr (anAttr); + QString newName = + LightApp_NameDlg::getName(getApp()->desktop(), nameAttr->Value().c_str()); + if (!newName.isEmpty()) { + nameAttr->SetValue(newName.toLatin1().constData()); + aListIO.First()->setName(newName.toLatin1().constData()); + } + } + + // Lock the study back if necessary + if (isLocked) { + studyDS->GetProperties()->SetLocked(true); + } + + // Update object browser + updateObjBrowser(); + + } +} - saveDockWidgetsState(); +/*! + \brief Delete the selected objects. +*/ +void PVGUI_Module::onDelete() +{ + LightApp_SelectionMgr* aSelectionMgr = getApp()->selectionMgr(); + SALOME_ListIO aListIO; + aSelectionMgr->selectedObjects(aListIO); + + if (aListIO.Extent() == 1 && aListIO.First()->hasEntry()) { + std::string entry = aListIO.First()->getEntry(); + + // Get SALOMEDS client study + _PTR(Study) studyDS = PARAVIS::GetCStudy(this); + if(!studyDS) { + return; + } + + // Unlock the study if it is locked + bool isLocked = studyDS->GetProperties()->IsLocked(); + if (isLocked) { + studyDS->GetProperties()->SetLocked(false); + } + + // Remove the selected state from the study + _PTR(StudyBuilder) studyBuilder = studyDS->NewBuilder(); + _PTR(SObject) stateSObj = studyDS->FindObjectID(entry); + studyBuilder->RemoveObject(stateSObj); + + // Lock the study back if necessary + if (isLocked) { + studyDS->GetProperties()->SetLocked(true); + } + + // Update object browser + updateObjBrowser(); + } +} - return LightApp_Module::deactivateModule( study ); +/*! + \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 Compares the contents of the window with the given reference image, - returns true if they "match" within some tolerance. + \brief Load selected paraview state + + If toClear == true, the current state will be cleared */ -bool PVGUI_Module::compareView( const QString& ReferenceImage, double Threshold, - ostream& Output, const QString& TempDirectory ) +void PVGUI_Module::loadSelectedState(bool toClear) { - if ( Implementation ) - return Implementation->Core.compareView( ReferenceImage, Threshold, Output, TempDirectory ); - return false; + 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")); + } } +void PVGUI_Module::onRepresentationChanged(pqRepresentation*) { + + + //rnv: to fix the issue "21712: [CEA 581] Preference to display legend by default" + // find the pqDisplayColorWidget instances and connect the variableChanged SIGNAL on the + // onVariableChanged slot of this class. This connection needs to change visibility + // of the "Colored Legend" after change the "Color By" array. + QList aWidget = getApp()->desktop()->findChildren(); + + for (int i = 0; i < aWidget.size() ; i++ ) { + if( aWidget[i] ) { + connect( aWidget[i], SIGNAL ( variableChanged ( pqVariableType, const QString ) ), + this, SLOT(onVariableChanged( pqVariableType, const QString) ), Qt::UniqueConnection ); + } + } +} + + /*! \fn CAM_Module* createModule(); \brief Export module instance (factory function). @@ -746,7 +1554,18 @@ bool PVGUI_Module::compareView( const QString& ReferenceImage, double Threshold, #endif // WNT extern "C" { + + bool flag = false; PVGUI_EXPORT CAM_Module* createModule() { + if(!flag) { + vtkEDFHelperInit(); + flag = true; + } return new PVGUI_Module(); } + + PVGUI_EXPORT char* getModuleVersion() { + return (char*)PARAVIS_VERSION_STR; + } + }